diff --git a/README.md b/README.md index 1f71b14..3fc17e4 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ C Macro Collections Logo

-

Easy to use, header only, macro generated, generic and type-safe Data Structures in C.

+

Easy to use, modular, header only, macro based, generic and type-safe Data Structures in C.

LinkToRepo @@ -39,7 +39,7 @@ No installation is required. The entire library is made of header files and can ## Contributing -There is a lot to be done. You can check the `TODO` file in the root of the repository or the issues in the github page. Also, tests and documentation are in constant development. Also check out the `STATUS` file for the status on the development of the library. +There is a lot to be done. You can check the `TODO` file in the root of the repository or the issues in the github page. Also, tests and documentation are in constant development. ## Usage diff --git a/STATUS b/STATUS deleted file mode 100644 index 0c96bd4..0000000 --- a/STATUS +++ /dev/null @@ -1,72 +0,0 @@ -Approximate completion of the library - -[ 99 ][ 99 ][ 99 ] % -[source][tests][docs] - -## - Finished - -[30][15][01] Library - -[91][45][01] CMC - [40][40][05] BitSet - [##][##][10] Deque - [80][70][00] HashBidiMap - [##][##][00] HashMap - [##][20][00] HashMultiMap - [##][20][00] HashMultiSet - [##][40][00] HashSet - [##][30][00] Heap - [##][40][00] IntervalHeap - [90][20][00] LinkedList - [90][30][00] List - [##][60][00] Queue - [00][00][00] SkipList - [80][20][00] SortedList - [95][90][00] Stack - [00][00][00] TreeBidiMap - [95][20][00] TreeMap - [00][00][00] TreeMultiMap - [00][00][00] TreeMultiSet - [95][20][00] TreeSet -[00][00][00] SAC - [00][00][00] BitSet - [00][00][00] Deque - [00][00][00] HashBidiMap - [00][00][00] HashMap - [00][00][00] HashMultiMap - [00][00][00] HashMultiSet - [00][00][00] HashSet - [00][00][00] Heap - [00][00][00] IntervalHeap - [00][00][00] LinkedList - [00][00][00] List - [00][00][00] Queue - [00][00][00] SkipList - [00][00][00] SortedList - [00][00][00] Stack - [00][00][00] TreeBidiMap - [00][00][00] TreeMap - [00][00][00] TreeMultiMap - [00][00][00] TreeMultiSet - [00][00][00] TreeSet -[00][00][00] TSC - [00][00][00] BitSet - [00][00][00] Deque - [00][00][00] HashBidiMap - [00][00][00] HashMap - [00][00][00] HashMultiMap - [00][00][00] HashMultiSet - [00][00][00] HashSet - [00][00][00] Heap - [00][00][00] IntervalHeap - [00][00][00] LinkedList - [00][00][00] List - [00][00][00] Queue - [00][00][00] SkipList - [00][00][00] SortedList - [00][00][00] Stack - [00][00][00] TreeBidiMap - [00][00][00] TreeMap - [00][00][00] TreeMultiMap - [00][00][00] TreeMultiSet - [00][00][00] TreeSet diff --git a/autogen.py b/autogen.py deleted file mode 100644 index 7c8f247..0000000 --- a/autogen.py +++ /dev/null @@ -1,502 +0,0 @@ -# A script for automation - -import argparse -import os -import pathlib -import re -import shutil -import subprocess -import sys -from typing import List, Text - -# Config Script Configuration -# Directories Names for directories -# Files Names for files -# Compiler Compiler Configurations -# Macro Expansion Configuration for the code expansion -# Collections All collections -# -# Variables marked as const are to not be modified - -# Directories - -# Output directory -# In this directory it is assumed that the following files and directories are -# included: main.c, codecov.c, unt folder -OUTPUT_DIR = './tests' -# Where the unit test files are -UNT_DIR = f'{OUTPUT_DIR}/unt' -# Directory mapping -DIR_MAP = {'HEADER': 'include', 'SOURCE': 'src'} -# File extension mapping -EXT_MAP = {'HEADER': 'h', 'SOURCE': 'c'} -# Where compilation objects will be outputted -BUILD_DIR = f'{OUTPUT_DIR}/build' -# const -INCLUDE_DIR = f"{OUTPUT_DIR}/{DIR_MAP['HEADER']}" -# const -SRC_DIR = f"{OUTPUT_DIR}/{DIR_MAP['SOURCE']}" -# Where executables go -BIN_DIR = f'{BUILD_DIR}/bin' -# Where object files .o go -OBJ_DIR = BUILD_DIR -# Where .gcov files should go -GCOV_DIR = f'{BUILD_DIR}/gcov' - -# Files -# All const - -# The name of the main test -MAIN = 'main' -# The name of the code coverage file -CODECOV = 'codecov' -# The name of the single test file -SINGLE = 'single' - -# Compiler - -# Compiler to be used -CC = 'gcc' -# Compilation Flags -CFLAGS = ['-Wall', '-Werror', '-O3'] -# Link flags -LFLAGS = [] -# Coverage Flags -CVFLAGS = ['--coverage', '-O0'] -# gcov flags -GCOV_FLAGS = [] -# Include of the main library -# const -INCLUDE = ['-I', './src'] -# Include to the test file headers -# const -TINCLUDE = ['-I', f'{INCLUDE_DIR}', '-I', f'{UNT_DIR}'] -# Include to code coverage -# const -CVINCLUDE = ['-I', INCLUDE_DIR, '-I', SRC_DIR, '-I', f'{UNT_DIR}'] - -# Macro Expansion - -# -E Only preprocessor -# -P No linemarkers -# -C Keep comments, except those inside macros (for UNIQUE_FLAG) -# const -EXPAND_FLAGS = '-E -P -C' -# Used to delimiter where the actual code starts and ends. Used by regex. -# Needs to be a valid C comment. -UNIQUE_FLAG = '// C_MACRO_COLLECTIONS_CODE' -# Temporary file used to expand the macros -TMP_FILE = './main.c' - - -# All collections that can be used for testing -COLLECTIONS = [ - # header, library, collection, pfx, sname, size, key, val - {'h': '"cmc_bitset.h"', 'LIB': 'CMC', 'COLLECTION': 'BITSET', 'PFX': 'bs', 'SNAME': 'bitset', 'SIZE': '', 'K': '', 'V': '' }, - {'h': '"cmc_deque.h"', 'LIB': 'CMC', 'COLLECTION': 'DEQUE', 'PFX': 'd', 'SNAME': 'deque', 'SIZE': '', 'K': '', 'V': 'size_t'}, - {'h': '"cmc_hashbidimap.h"', 'LIB': 'CMC', 'COLLECTION': 'HASHBIDIMAP', 'PFX': 'hbm', 'SNAME': 'hashbidimap', 'SIZE': '', 'K': 'size_t', 'V': 'size_t'}, - {'h': '"cmc_hashmap.h"', 'LIB': 'CMC', 'COLLECTION': 'HASHMAP', 'PFX': 'hm', 'SNAME': 'hashmap', 'SIZE': '', 'K': 'size_t', 'V': 'size_t'}, - {'h': '"cmc_hashmultimap.h"', 'LIB': 'CMC', 'COLLECTION': 'HASHMULTIMAP', 'PFX': 'hmm', 'SNAME': 'hashmultimap', 'SIZE': '', 'K': 'size_t', 'V': 'size_t'}, - {'h': '"cmc_hashmultiset.h"', 'LIB': 'CMC', 'COLLECTION': 'HASHMULTISET', 'PFX': 'hms', 'SNAME': 'hashmultiset', 'SIZE': '', 'K': '', 'V': 'size_t'}, - {'h': '"cmc_hashset.h"', 'LIB': 'CMC', 'COLLECTION': 'HASHSET', 'PFX': 'hs', 'SNAME': 'hashset', 'SIZE': '', 'K': '', 'V': 'size_t'}, - {'h': '"cmc_heap.h"', 'LIB': 'CMC', 'COLLECTION': 'HEAP', 'PFX': 'h', 'SNAME': 'heap', 'SIZE': '', 'K': '', 'V': 'size_t'}, - {'h': '"cmc_intervalheap.h"', 'LIB': 'CMC', 'COLLECTION': 'INTERVALHEAP', 'PFX': 'ih', 'SNAME': 'intervalheap', 'SIZE': '', 'K': '', 'V': 'size_t'}, - {'h': '"cmc_linkedlist.h"', 'LIB': 'CMC', 'COLLECTION': 'LINKEDLIST', 'PFX': 'll', 'SNAME': 'linkedlist', 'SIZE': '', 'K': '', 'V': 'size_t'}, - {'h': '"cmc_list.h"', 'LIB': 'CMC', 'COLLECTION': 'LIST', 'PFX': 'l', 'SNAME': 'list', 'SIZE': '', 'K': '', 'V': 'size_t'}, - {'h': '"cmc_queue.h"', 'LIB': 'CMC', 'COLLECTION': 'QUEUE', 'PFX': 'q', 'SNAME': 'queue', 'SIZE': '', 'K': '', 'V': 'size_t'}, - {'h': '"cmc_sortedlist.h"', 'LIB': 'CMC', 'COLLECTION': 'SORTEDLIST', 'PFX': 'sl', 'SNAME': 'sortedlist', 'SIZE': '', 'K': '', 'V': 'size_t'}, - {'h': '"cmc_stack.h"', 'LIB': 'CMC', 'COLLECTION': 'STACK', 'PFX': 's', 'SNAME': 'stack', 'SIZE': '', 'K': '', 'V': 'size_t'}, - {'h': '"cmc_treemap.h"', 'LIB': 'CMC', 'COLLECTION': 'TREEMAP', 'PFX': 'tm', 'SNAME': 'treemap', 'SIZE': '', 'K': 'size_t', 'V': 'size_t'}, - {'h': '"cmc_treeset.h"', 'LIB': 'CMC', 'COLLECTION': 'TREESET', 'PFX': 'ts', 'SNAME': 'treeset', 'SIZE': '', 'K': '', 'V': 'size_t'} -] - - -# Just a realy helpfull overview -CONFIG = f'''Directory Settings - OUTPUT_DIR = {OUTPUT_DIR} - UNT_DIR = {UNT_DIR} - DIR_MAP = {DIR_MAP} - EXT_MAP = {EXT_MAP} - BUILD_DIR = {BUILD_DIR} - INCLUDE_DIR = {INCLUDE_DIR} - SRC_DIR = {SRC_DIR} - OBJ_DIR = {OBJ_DIR} - GCOV_DIR = {GCOV_DIR} -File Settings - MAIN = {MAIN} - CODECOV = {CODECOV} - SINGLE = {SINGLE} -Compiler Settings - CC = {CC} - CFLAGS = {CFLAGS} - LFLAGS = {LFLAGS} - CVFLAGS = {CVFLAGS} - GCOV_FLAGS = {GCOV_FLAGS} - INCLUDE = {INCLUDE} - TINCLUDE = {TINCLUDE} - CVINCLUDE = {CVINCLUDE} -Macro Expansion - EXPAND_FLAGS = {EXPAND_FLAGS} - UNIQUE_FLAG = {UNIQUE_FLAG} - TMP_FILE = {TMP_FILE}''' - - -def full_path(path: Text) -> Text: - ''' - Returns the full path of a 'path' with ralative paths, e.g. './' or '../' - ''' - return str(pathlib.Path(path).resolve()) - - -def execute_command(commands: List[Text]): - cmd = ' '.join(commands) - print(cmd) - subprocess.check_call(cmd, shell=True) - - # if cp.returncode != 0: - # print('Error when executing the last command') - # exit(1) - - -def require_executable(program: Text): - ''' - Asserts that a given program is installed and available in PATH. Raises an exception if it doesn't. - ''' - if shutil.which(program) is None: - raise Exception(f'The required executable {program} was not found in your path') - - -def require_file(file: Text): - ''' - Asserts that a given file exists. Raises an exception if it doesn't. - ''' - f = pathlib.Path(file).resolve() - if not f.is_file(): - raise Exception(f'The required file {str(f)} was not found') - - -def assert_dir(directory: Text): - ''' - Given a string 'directory' that is a path to a directory, make sure that it exists. - ''' - # TODO change this to use pathlib ? - if not os.path.exists(directory): - os.makedirs(directory) - - -def assert_structure(): - ''' - Git might not commit some required directories. This function asserts that they exist. - ''' - assert_dir(OUTPUT_DIR) - - # include and src - for directory in DIR_MAP.values(): - assert_dir(f'{OUTPUT_DIR}/{directory}') - - assert_dir(BUILD_DIR) - assert_dir(OBJ_DIR) - assert_dir(BIN_DIR) - assert_dir(GCOV_DIR) - - -def format_code(source: bool, tests: bool): - ''' - Format all source files from the main library or test files. - ''' - if source: - execute_command(['find', './src/', '-name', '*.h', '|', 'xargs', 'clang-format', '--style=file', '--verbose', '-i']) - if tests: - execute_command(['find', './tests/', '-name', '*.c', '-o', '-name', '*.h', '|', 'xargs', 'clang-format', '--style=file', '--verbose', '-i']) - - -def clean_build(cleanfull: bool): - ''' - Removes all files generated by compilation and code coverage along with folders. - ''' - # -f prevents 'rm' from failing - execute_command(['rm', '-r', '-f', f'./*.gcov']) - execute_command(['rm', '-r', '-f', f'{OUTPUT_DIR}/*.exe']) - execute_command(['rm', '-r', '-f', BUILD_DIR]) - execute_command(['rm', '-f', './*.gcda']) - execute_command(['rm', '-f', './*.gcno']) - - if cleanfull: - execute_command(['rm', '-r', SRC_DIR]) - execute_command(['rm', '-r', INCLUDE_DIR]) - - -def expand_code(): - ''' - Expands code to be used in tests. This is necessary because code coverage doesn't work with macros. - ''' - # Generate Header and Source separately - for ftype in ['HEADER', 'SOURCE']: - for data in COLLECTIONS: - file = open(TMP_FILE, 'w') - - file.write( - f''' - #include "macro_collections.h" - - {UNIQUE_FLAG} - - C_MACRO_COLLECTIONS_ALL_{ftype}({data['LIB']}, {data['COLLECTION']}, PUBLIC, ({', '.join([data['PFX'], data['SNAME'], data['SIZE'], data['K'], data['V']])})) - - {UNIQUE_FLAG} - ''') - - file.flush() - file.close() - - result = subprocess.getoutput(f'{CC} {EXPAND_FLAGS} {" ".join(INCLUDE)} {TMP_FILE}') - - # (?s) makes '.' match anything, even '\n' - match = re.search(fr'(?s){UNIQUE_FLAG}(?P.+){UNIQUE_FLAG}', result) - - if match is None: - os.remove(TMP_FILE) - print('Didn\'t match FLAG. Probably because compilation failed.', file=sys.stderr) - exit(1) - - file = open(f'{OUTPUT_DIR}/{DIR_MAP[ftype]}/tst_{data["LIB"].lower()}_{data["SNAME"]}.{EXT_MAP[ftype]}', 'w') - - if ftype == 'HEADER': - file.write( - f''' - #ifndef CMC_{data['LIB']}_{data['COLLECTION']}_TEST_H - #define CMC_{data['LIB']}_{data['COLLECTION']}_TEST_H - - #include "macro_collections.h" - {match.group('code')} - - #endif /* CMC_{data['LIB']}_{data['COLLECTION']}_TEST_H */ - ''') - else: - file.write( - f''' - #include {'"tst_' + data["h"][1:]} - - {match.group("code")} - ''') - - file.flush() - file.close() - - print(f'''Generated {'"tst_' + data["h"][1:]: >24} -> {OUTPUT_DIR}/{DIR_MAP[ftype]}/tst_{data["LIB"].lower()}_{data["SNAME"]}.{EXT_MAP[ftype]}''') - - os.remove(TMP_FILE) - - -def format_expand(): - ''' - Format the files outputted by 'expand_code'. - ''' - cmd = ['clang-format', '--style=file', '--verbose', '-i'] - dirs_to_format = [f'{OUTPUT_DIR}/{DIR_MAP[ftype]}/*.{EXT_MAP[ftype]}' for ftype in DIR_MAP.keys()] - cmd.extend(dirs_to_format) - execute_command(cmd) - - -def build_main(): - ''' - Build all object files and main.c for tests. - ''' - for data in COLLECTIONS: - cmd = [CC] - cmd += TINCLUDE # This one needs to go first - cmd += INCLUDE - cmd += ['-c', f"{SRC_DIR}/tst_{data['LIB'].lower()}_{data['SNAME']}.c"] - cmd += ['-o', f"{OBJ_DIR}/tst_{data['LIB'].lower()}_{data['SNAME']}.o"] - execute_command(cmd) - - # Build OUTPUT_DIR/main.c - cmd = [CC] - cmd += TINCLUDE # This one needs to go first - cmd += INCLUDE - cmd += ['-c', f'{OUTPUT_DIR}/{MAIN}.c'] - cmd += ['-o', f'{OBJ_DIR}/{MAIN}.o'] - execute_command(cmd) - - # Link everything producing OUTPUT_DIR/main.exe - cmd = [CC] - cmd += LFLAGS - cmd += ['-o', f'{BIN_DIR}/{MAIN}.exe'] - cmd += [f'{OBJ_DIR}/main.o'] - cmd += [f'{OBJ_DIR}/tst_{data["LIB"].lower()}_{data["SNAME"]}.o' for data in COLLECTIONS] - execute_command(cmd) - - -def run_main(): - ''' - Runs main.exe - ''' - execute_command([full_path(f'{BIN_DIR}/{MAIN}.exe')]) - - -def build_codecov(): - ''' - Builds codecov.c for code coverage. - ''' - cmd = [CC] - cmd += CVFLAGS - cmd += CVINCLUDE # This one needs to go first - cmd += INCLUDE - cmd += [f'{OUTPUT_DIR}/{CODECOV}.c'] - cmd += ['-o', f'{BIN_DIR}/{CODECOV}.exe'] - execute_command(cmd) - - -def run_codecov(): - ''' - Runs codecov.exe and then gcov on the generated gcda files. All gcov files then go to GCOV_DIR. - ''' - execute_command([full_path(f'{BIN_DIR}/{CODECOV}.exe')]) - execute_command(['gcov'] + GCOV_FLAGS + [f'{CODECOV}.gcda']) - execute_command(['rm', '*.h.gcov']) - - -def tidy(): - ''' - Places files to their respective directory. - ''' - execute_command(['mv', '*.gcov', GCOV_DIR]) - - -if __name__ == '__main__': - p = argparse.ArgumentParser('autogen.py', usage='%(prog)s [options]') - - p.add_argument('-sc', '--show-config', - help='Displays the current configuration', - default=False, - action='store_true', - dest='config') - - source = p.add_argument_group('source', 'For dealing with the source files and formatting') - - expand = p.add_argument_group('expand', 'For dealing with code generation and formatting for tests') - - task = p.add_argument_group('task', 'Specify a task (mutually exclusive)') - task_ = task.add_mutually_exclusive_group() - - action = p.add_argument_group('action', 'Actions on task') - - task_.add_argument('-cv', '--codecov', - help='Designates task as code coverage (uses codecov.c)', - default=False, - action='store_true', - dest='codecov') - task_.add_argument('-m', '--main', - help='Designates task as the main tests (uses main.c)', - default=False, - action='store_true', - dest='main') - task_.add_argument('-s', '--single', - help='Designates task as an individual test (uses single.c)', - dest='single') - - expand.add_argument('-c', '--clean', - help='Cleans all build objects', - default=False, - action='store_true', - dest='clean') - expand.add_argument('-cf', '--clean-full', - help='Cleans all build objects, source and header files, and removes folders', - default=False, - action='store_true', - dest='cleanfull') - expand.add_argument('-e', '--expand', - help='Expands the header and source files', - default=False, - action='store_true', - dest='expand') - expand.add_argument('-nf', '--no-format', - help='Does not format the output of expand. Can be used when you might not have clang-format', - default=False, - action='store_true', - dest='noformat') - expand.add_argument('-nt', '--no-tidy', - help='Don\'t move files around', - default=False, - action='store_true', - dest='notidy') - - action.add_argument('-b', '--build', - help='Build task', - default=False, - action='store_true', - dest='build') - action.add_argument('-r', '--run', - help='Run task', - default=False, - action='store_true', - dest='run') - - source.add_argument('-fs', '--format-source', - help='Format the source code', - default=False, - action='store_true', - dest='fmt_source') - source.add_argument('-ft', '--format-tests', - help='Format tests files', - default=False, - action='store_true', - dest='fmt_tests') - - args = p.parse_args() - - has_target = args.main or args.codecov or args.single - - if args.config: - print(CONFIG) - exit(0) - - if args.fmt_source or args.fmt_tests: - require_executable('find') - require_executable('xargs') - format_code(args.fmt_source, args.fmt_tests) - # Prevent mixing code - exit(0) - - if not args.cleanfull: - assert_structure() - if args.clean: - clean_build(False) - else: - clean_build(True) - # Nothing else will work, so just exit - exit(0) - - if args.expand: - expand_code() - if not args.noformat: - require_executable('clang-format') - format_expand() - else: - # In case the next task is to build the code from source - # This warning is a very annoying one from gcc - CFLAGS += ['-Wno-misleading-indentation'] - - if args.build: - require_executable(CC) - if args.codecov: - require_executable('gcov') - - if args.codecov: - require_file(f'{OUTPUT_DIR}/{CODECOV}.c') - if args.build: - build_codecov() - if args.run: - run_codecov() - elif args.main: - require_file(f'{OUTPUT_DIR}/{MAIN}.c') - if args.build: - build_main() - if args.run: - run_main() - elif args.single: - require_file(f'{OUTPUT_DIR}/{SINGLE}.c') - # TODO - - if not args.notidy and args.codecov: - tidy() diff --git a/benchmarks/C++ Comparison/hashtable/hashmap.c b/benchmarks/C++ Comparison/hashtable/hashmap.c deleted file mode 100644 index 5956b8b..0000000 --- a/benchmarks/C++ Comparison/hashtable/hashmap.c +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef COUNT -#error "Please define COUNT" -#endif - -#include "murmurhash.h" - -#include "macro_collections.h" - -#include "../../util/twister.c" - -CMC_CMC_HASHMAP_CORE(PUBLIC, HEADER, (hm, hashmap, , uint64_t, uint64_t)) -CMC_CMC_HASHMAP_CORE(PUBLIC, SOURCE, (hm, hashmap, , uint64_t, uint64_t)) - -int cmp(uint64_t a, uint64_t b) -{ - return (a > b) - (a < b); -} - -// size_t hash(uint64_t a) -// { -// size_t x = (size_t)a; -// x = ((x >> 16) ^ x) * 0x45d9f3b; -// x = ((x >> 16) ^ x) * 0x45d9f3b; -// x = (x >> 16) ^ x; -// return x; -// } - -size_t hash(uint64_t k) -{ - static size_t seed = 211106232532969; - return MurMurHash(&k, sizeof(k), seed); -} - -struct hashmap_fkey *fkey = &(struct hashmap_fkey) { - .cmp = cmp, - .hash = hash, - NULL -}; - -struct hashmap_fval *fval = &(struct hashmap_fval) { - .cmp = cmp, - .hash = hash, - NULL -}; - -int main(void) -{ - mt_state tw; - twist_init(&tw, 50331653); - - struct hashmap *map = hm_new(COUNT, 0.6, fkey, fval); - - for (uint64_t i = 0; i < COUNT; i++) - { - uint64_t v = twist_uint64(&tw); - hm_insert(map, v, v); - } - - hm_free(map); - - return 0; -} diff --git a/benchmarks/C++ Comparison/hashtable/hashmultimap.c b/benchmarks/C++ Comparison/hashtable/hashmultimap.c deleted file mode 100644 index 4f25db7..0000000 --- a/benchmarks/C++ Comparison/hashtable/hashmultimap.c +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef COUNT -#error "Please define COUNT" -#endif - -#include "murmurhash.h" - -#include "macro_collections.h" - -#include "../../util/twister.c" - -CMC_CMC_HASHMULTIMAP_CORE(PUBLIC, HEADER, (hmm, hashmultimap, , uint64_t, uint64_t)) -CMC_CMC_HASHMULTIMAP_CORE(PUBLIC, SOURCE, (hmm, hashmultimap, , uint64_t, uint64_t)) - -int cmp(uint64_t a, uint64_t b) -{ - return (a > b) - (a < b); -} - -// size_t hash(uint64_t a) -// { -// size_t x = (size_t)a; -// x = ((x >> 16) ^ x) * 0x45d9f3b; -// x = ((x >> 16) ^ x) * 0x45d9f3b; -// x = (x >> 16) ^ x; -// return x; -// } - -size_t hash(uint64_t k) -{ - static size_t seed = 211106232532969; - return MurMurHash(&k, sizeof(k), seed); -} - -struct hashmultimap_fkey *fkey = &(struct hashmultimap_fkey) { - .cmp = cmp, - .hash = hash, - NULL -}; - -struct hashmultimap_fval *fval = &(struct hashmultimap_fval) { - .cmp = cmp, - .hash = hash, - NULL -}; - -int main(void) -{ - mt_state tw; - twist_init(&tw, 50331653); - - struct hashmultimap *map = hmm_new(COUNT, 0.6, fkey, fval); - - for (uint64_t i = 0; i < COUNT; i++) - { - uint64_t v = twist_uint64(&tw); - hmm_insert(map, v, v); - } - - hmm_free(map); - - return 0; -} diff --git a/benchmarks/C++ Comparison/hashtable/murmurhash.h b/benchmarks/C++ Comparison/hashtable/murmurhash.h deleted file mode 100644 index a334dd9..0000000 --- a/benchmarks/C++ Comparison/hashtable/murmurhash.h +++ /dev/null @@ -1,58 +0,0 @@ -// https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/libsupc%2B%2B/hash_bytes.cc - -#ifndef MURMURHASH -#define MURMURHASH - -#include - -inline size_t unaligned_load(const char *p) -{ - size_t result; - memcpy(&result, p, sizeof(result)); - return result; -} - -inline size_t load_bytes(const char *p, int n) -{ - size_t result = 0; - --n; - do - { - result = (result << 8) + (unsigned char)(p[n]); - } while (--n >= 0); - return result; -} - -inline size_t shift_mix(size_t v) -{ - return v ^ (v >> 47); -} - -size_t MurMurHash(const void *ptr, size_t len, size_t seed) -{ - static const size_t mul = (((size_t)0xc6a4a793UL) << 32UL) + (size_t)0x5bd1e995UL; - const char *const buf = (const char *)(ptr); - - // Remove the bytes not divisible by the sizeof(size_t). This - // allows the main loop to process the data as 64-bit integers. - const size_t len_aligned = len & ~(size_t)0x7; - const char *const end = buf + len_aligned; - size_t hash = seed ^ (len * mul); - for (const char *p = buf; p != end; p += 8) - { - const size_t data = shift_mix(unaligned_load(p) * mul) * mul; - hash ^= data; - hash *= mul; - } - if ((len & 0x7) != 0) - { - const size_t data = load_bytes(end, len & 0x7); - hash ^= data; - hash *= mul; - } - hash = shift_mix(hash) * mul; - hash = shift_mix(hash); - return hash; -} - -#endif /* MURMURHASH */ diff --git a/benchmarks/C++ Comparison/hashtable/script.py b/benchmarks/C++ Comparison/hashtable/script.py deleted file mode 100644 index bd939ec..0000000 --- a/benchmarks/C++ Comparison/hashtable/script.py +++ /dev/null @@ -1,57 +0,0 @@ -import os -import sys -import time -import subprocess - -ITERATIONS = 10 -COUNT = 20000000 -VERBOSE = False - -NL = '\n' - -INCLUDE = "../../../src" -CC = 'gcc' -CCPP = 'g++' # LoL -OPT = '-O3' - -print(f'Using {CC} compiler') - - -def execute_command(commands): - print(' '.join(commands)) - subprocess.run(commands, shell=True) - - -# Common args -args = ['-I', INCLUDE, OPT, f'-DCOUNT={COUNT}', '-DCMC_NO_CALLBACKS'] - -map_args = [CC, 'hashmap.c', '-o', 'hashmap.exe'] -mmap_args = [CC, 'hashmultimap.c', '-o', 'hashmultimap.exe'] -cpp_args = [CCPP, 'unorderedmap.cpp', '-I', INCLUDE, '-o', 'unorderedmap.exe', OPT, f'-DCOUNT={COUNT}'] - -map_args.extend(args) -mmap_args.extend(args) -cpp_args.extend(args) - -execute_command(map_args) -execute_command(mmap_args) -execute_command(cpp_args) - -programs = ['hashmap.exe', 'hashmultimap.exe', 'unorderedmap.exe'] - -for prog in programs: - total = 0 - for i in range(ITERATIONS): - print(f'{i}...', end='') - sys.stdout.flush() - start_time = time.time() - subprocess.run(prog, shell=True) - - delta = time.time() - start_time - total += delta - - if VERBOSE: - print(f'({delta})') - - avg = total / ITERATIONS - print(f'{"" if VERBOSE else NL}{avg} seconds for {COUNT} -> AVG[{int((avg * 1e9) / COUNT)} ns] [{prog}]{NL if VERBOSE else ""}') diff --git a/benchmarks/C++ Comparison/hashtable/unorderedmap.cpp b/benchmarks/C++ Comparison/hashtable/unorderedmap.cpp deleted file mode 100644 index 5f59f00..0000000 --- a/benchmarks/C++ Comparison/hashtable/unorderedmap.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef COUNT -#error "Please define COUNT" -#endif - -#include "murmurhash.h" - -#include - -#include "../../util/twister.c" - -struct IntHasher -{ - std::size_t operator()(const uint64_t& k) const - { - static size_t seed = 211106232532969; - return MurMurHash(&k, sizeof(k), seed); - } -}; - -int main(void) -{ - mt_state tw; - twist_init(&tw, 50331653); - - std::unordered_map map(COUNT); - - for (uint64_t i = 0; i < COUNT; i++) - { - uint64_t v = twist_uint64(&tw); - map.insert({v, v}); - } - - return 0; -} diff --git a/benchmarks/benchmark.c b/benchmarks/benchmark.c deleted file mode 100644 index 952b973..0000000 --- a/benchmarks/benchmark.c +++ /dev/null @@ -1,253 +0,0 @@ -/** - * benchmark.c - * - * Creation Date: 13/04/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - * Benchmarks: - * - Input - * - Search - * - Iteration - * - Output - */ -#include "macro_collections.h" -#include "util/twister.c" -#include -#include -#include -#include -#include - -#define NTOTAL UINT64_C(10000000) -#define NMIN UINT64_C(100) - -// Percentage % macro -#define PC(x) x * 100.0 - -static int intcmp(int a, int b) -{ - return a - b; -} - -static size_t inthash(int t) -{ - size_t a = t; - a += ~(a << 15); - a ^= (a >> 10); - a += (a << 3); - a ^= (a >> 6); - a += ~(a << 11); - a ^= (a >> 16); - return a; -} - -size_t randsize(size_t min, size_t max, mt_state_ptr st) -{ - return (size_t)floor(twist_real(st) * ((double)max - (double)min + 1.0) + (double)min); -} - -void shuffle(int *array, mt_state_ptr st) -{ - for (size_t i = 0; i < NTOTAL; i++) - { - size_t j = randsize(0, NTOTAL - 1, st); - int tmp = array[j]; - array[j] = array[i]; - array[i] = tmp; - } -} - -CMC_COLLECTION_GENERATE(DEQUE, d, deque, /* K */, int) -CMC_COLLECTION_GENERATE(HASHMAP, hm, hmap, int, int) -CMC_COLLECTION_GENERATE(HASHSET, hs, hset, /* K */, int) -CMC_COLLECTION_GENERATE(HEAP, h, heap, /* K */, int) -CMC_COLLECTION_GENERATE(LINKEDLIST, ll, linked, /* K */, int) -CMC_COLLECTION_GENERATE(LIST, l, list, /* K */, int) -CMC_COLLECTION_GENERATE(QUEUE, q, queue, /* K */, int) -CMC_COLLECTION_GENERATE(STACK, s, stack, /* K */, int) -CMC_COLLECTION_GENERATE(TREEMAP, tm, tmap, int, int) -CMC_COLLECTION_GENERATE(TREESET, ts, tset, /* K */, int) - -CMC_COLLECTION_GENERATE(INTERVALHEAP, ih, iheap, /* k */, int) -CMC_COLLECTION_GENERATE(MULTIMAP, mm, mmap, int, int) -CMC_COLLECTION_GENERATE(MULTISET, ms, mset, /* K */, int) - -#define BENCHMARK(NAME, PFX, sname, initfunc, insertbody, removebody, searchbody) \ - void NAME##_io_benchmark(int *array, int *sarray, size_t s) \ - { \ - printf("+------------------------------------------------------------ %10s\n", #NAME); \ - printf("+------------------------------------------------------------ \n"); \ - struct cmc_timer timer, total; \ - int r, k, v; \ - size_t j; \ - \ - struct sname *coll = initfunc; \ - \ - cmc_timer_start(total); \ - cmc_timer_start(timer); \ - \ - for (size_t i = 0; i < NTOTAL; i++) \ - { \ - insertbody; \ - } \ - \ - cmc_timer_stop(timer); \ - \ - cmc_timer_calc(timer); \ - \ - size_t s1 = PFX##_count(coll); \ - \ - printf(" INPUT %10s TOOK %8.0lf milliseconds for %8" PRIuMAX " elements\n", #NAME, timer.result, s1); \ - \ - double input_time = timer.result; \ - \ - cmc_timer_start(timer); \ - \ - for (size_t i = 0; i < s; i++) \ - { \ - searchbody; \ - } \ - \ - cmc_timer_stop(timer); \ - \ - cmc_timer_calc(timer); \ - \ - printf(" SEARCH %10s TOOK %8.0lf milliseconds for %8" PRIuMAX " elements\n", #NAME, timer.result, s); \ - \ - double search_time = timer.result; \ - \ - struct sname##_iter iter; \ - \ - cmc_timer_start(timer); \ - \ - for (PFX##_iter_init(&iter, coll); !PFX##_iter_end(&iter); PFX##_iter_next(&iter)) \ - { \ - } \ - \ - cmc_timer_stop(timer); \ - \ - cmc_timer_calc(timer); \ - \ - printf("ITERATION %10s TOOK %8.0lf milliseconds for %8" PRIuMAX " elements\n", #NAME, timer.result, s1); \ - \ - double iter_time = timer.result; \ - \ - cmc_timer_start(timer); \ - \ - for (size_t i = 0; i < NTOTAL; i++) \ - { \ - removebody; \ - } \ - \ - cmc_timer_stop(timer); \ - \ - cmc_timer_calc(timer); \ - \ - size_t s2 = PFX##_count(coll); \ - \ - printf(" OUTPUT %10s TOOK %8.0lf milliseconds for %8" PRIuMAX " elements\n", #NAME, timer.result, s1); \ - \ - double output_time = timer.result; \ - \ - cmc_timer_stop(total); \ - cmc_timer_calc(total); \ - \ - 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; \ - \ - printf("+------------------------------------------------------------ \n"); \ - printf("TOTAL TIME : %.0lf milliseconds\n", total.result); \ - printf("ADJUSTED TIME : %.0lf milliseconds\n", adj_search_time); \ - \ - printf("+------------------------------------------------------------ \n"); \ - printf(" INPUT : %5.2lf%% (%5.2f%%)\n", PC(input_time / total.result), PC(input_time / no_search)); \ - printf(" SEARCH : %5.2lf%%\n", PC(search_time / total.result)); \ - printf("ITERATION : %5.2lf%% (%5.2f%%)\n", PC(iter_time / total.result), PC(iter_time / no_search)); \ - printf(" OUTPUT : %5.2lf%% (%5.2f%%)\n", PC(output_time / total.result), PC(output_time / no_search)); \ - printf("+------------------------------------------------------------ \n"); \ - \ - assert(s1 == NTOTAL && s2 == 0); \ - \ - printf("+------------------------------------------------------------ %10s\n\n", #NAME); \ - } - -BENCHMARK(DEQUE, d, deque, d_new(NTOTAL), d_push_back(coll, array[i]), d_pop_back(coll), d_contains(coll, sarray[i], intcmp)) -BENCHMARK(HASHMAP, hm, hmap, hm_new(NTOTAL, 0.6, intcmp, inthash), hm_insert(coll, array[i], array[i]), hm_remove(coll, array[i], &r), hm_contains(coll, sarray[i])) -BENCHMARK(HASHSET, hs, hset, hs_new(NTOTAL, 0.6, intcmp, inthash), hs_insert(coll, array[i]), hs_remove(coll, array[i]), hs_contains(coll, sarray[i])) -BENCHMARK(HEAP, h, heap, h_new(NTOTAL, cmc_min_heap, intcmp), h_insert(coll, array[i]), h_remove(coll, &r), h_contains(coll, sarray[i])) -BENCHMARK(LINKEDLIST, ll, linked, ll_new(), ll_push_back(coll, array[i]), ll_pop_back(coll), ll_contains(coll, sarray[i], intcmp)) -BENCHMARK(LIST, l, list, l_new(NTOTAL), l_push_back(coll, array[i]), l_pop_back(coll), l_contains(coll, sarray[i], intcmp)) -BENCHMARK(QUEUE, q, queue, q_new(NTOTAL), q_enqueue(coll, array[i]), q_dequeue(coll), q_contains(coll, sarray[i], intcmp)) -BENCHMARK(STACK, s, stack, s_new(NTOTAL), s_push(coll, array[i]), s_pop(coll), s_contains(coll, sarray[i], intcmp)) -BENCHMARK(TREEMAP, tm, tmap, tm_new(intcmp), tm_insert(coll, array[i], array[i]), tm_remove(coll, array[i], &r), tm_contains(coll, sarray[i])) -BENCHMARK(TREESET, ts, tset, ts_new(intcmp), ts_insert(coll, array[i]), ts_remove(coll, array[i]), ts_contains(coll, sarray[i])) - -BENCHMARK(INTERVALHEAP, ih, iheap, ih_new(NTOTAL, intcmp), ih_insert(coll, array[i]), ih_remove_max(coll, &r), ih_contains(coll, sarray[i])) -BENCHMARK(MULTIMAP, mm, mmap, mm_new(NTOTAL, 0.8, intcmp, inthash), mm_insert(coll, array[i], array[i]), mm_remove(coll, array[i], &r), mm_contains(coll, sarray[i])) -BENCHMARK(MULTISET, ms, mset, ms_new(NTOTAL, 0.6, intcmp, inthash), ms_insert(coll, array[i]), ms_remove(coll, array[i]), ms_contains(coll, sarray[i])) - -int main(void) -{ - // Using the Mersenne Twister to generate random numbers. This seed - // guarantees that everytime this program runs it will generate the same - // random numbers. The random numbers influence on the shuffling of the - // array. - mt_state st; - twist_init(&st, UINT64_C(12604951237)); - - int *array = malloc(NTOTAL * sizeof(int)); - int *sarray = malloc(NTOTAL * sizeof(int)); - - if (!array) - { - printf("Allocation failed\n"); - return 1; - } - - for (int i = -5000000; i < 5000000; i++) - array[i + 5000000] = i; - - shuffle(array, &st); - - memcpy(sarray, array, NTOTAL * sizeof(int)); - - shuffle(sarray, &st); - - printf("\nNote: Adjusted Time refers to if the container had done a search over all %" PRIuMAX " elements.\n\n", NTOTAL); - - // Linear containers have to search for NMIN elements and non-linear (hash - // and tree) have to search for all elements. - struct cmc_timer timer; - cmc_timer_start(timer); - - DEQUE_io_benchmark(array, sarray, NMIN); - HASHMAP_io_benchmark(array, sarray, NTOTAL); - HASHSET_io_benchmark(array, sarray, NTOTAL); - HEAP_io_benchmark(array, sarray, NMIN); - LINKEDLIST_io_benchmark(array, sarray, NMIN); - LIST_io_benchmark(array, sarray, NMIN); - QUEUE_io_benchmark(array, sarray, NMIN); - STACK_io_benchmark(array, sarray, NMIN); - TREEMAP_io_benchmark(array, sarray, NTOTAL); - TREESET_io_benchmark(array, sarray, NTOTAL); - - INTERVALHEAP_io_benchmark(array, array, NMIN); - MULTIMAP_io_benchmark(array, array, NTOTAL); - MULTISET_io_benchmark(array, array, NTOTAL); - - cmc_timer_stop(timer); - cmc_timer_calc(timer); - - printf("+-----------------------------------------------------------+ \n"); - printf("| Total Benchmark Running Time : %12.0lf seconds | \n", timer.result / 1000); - printf("+-----------------------------------------------------------+ \n"); - - free(array); - free(sarray); - - return 0; -} diff --git a/benchmarks/compile_time/Makefile b/benchmarks/compile_time/Makefile deleted file mode 100644 index de4d833..0000000 --- a/benchmarks/compile_time/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -main: - gcc compile_time.c -c -O3 -ftime-report -I ../../src \ No newline at end of file diff --git a/benchmarks/compile_time/compile_time.c b/benchmarks/compile_time/compile_time.c deleted file mode 100644 index 02bc122..0000000 --- a/benchmarks/compile_time/compile_time.c +++ /dev/null @@ -1,178 +0,0 @@ -/* Compilation time for over 90 collections */ -#include - -struct imaginary -{ - double real; - double imag; -}; - -enum app_state -{ - TRACE = 1, - DEBUG = 2, - INFO = 3, - WARN = 4, - ERROR = 5, - FATAL = 6 -}; - -CMC_COLLECTION_GENERATE(BIDIMAP, bd0, bidimap0, struct imaginary, struct imaginary) -CMC_COLLECTION_GENERATE(DEQUE, d0, deque0, /* K */, struct imaginary) -CMC_COLLECTION_GENERATE(HASHMAP, hm0, hmap0, struct imaginary, struct imaginary) -CMC_COLLECTION_GENERATE(HASHSET, hs0, hset0, /* K */, struct imaginary) -CMC_COLLECTION_GENERATE(HEAP, h0, heap0, /* K */, struct imaginary) -CMC_COLLECTION_GENERATE(INTERVALHEAP, ih0, iheap0, struct imaginary, struct imaginary) -CMC_COLLECTION_GENERATE(LINKEDLIST, ll0, linked0, /* K */, struct imaginary) -CMC_COLLECTION_GENERATE(LIST, l0, list0, /* K */, struct imaginary) -CMC_COLLECTION_GENERATE(MULTIMAP, mm0, mmap0, struct imaginary, struct imaginary) -CMC_COLLECTION_GENERATE(MULTISET, ms0, mset0, /* K */, struct imaginary) -CMC_COLLECTION_GENERATE(STACK, s0, stack0, /* K */, struct imaginary) -CMC_COLLECTION_GENERATE(SORTEDLIST, sl0, sotredlist0, /* K */, struct imaginary) -CMC_COLLECTION_GENERATE(QUEUE, q0, queue0, /* K */, struct imaginary) -CMC_COLLECTION_GENERATE(TREESET, ts0, tset0, /* K */, struct imaginary) -CMC_COLLECTION_GENERATE(TREEMAP, tm0, tmap0, struct imaginary, struct imaginary) - -CMC_COLLECTION_GENERATE(BIDIMAP, bd1, bidimap1, int, int) -CMC_COLLECTION_GENERATE(DEQUE, d1, deque1, /* K */, int) -CMC_COLLECTION_GENERATE(HASHMAP, hm1, hmap1, int, int) -CMC_COLLECTION_GENERATE(HASHSET, hs1, hset1, /* K */, int) -CMC_COLLECTION_GENERATE(HEAP, h1, heap1, /* K */, int) -CMC_COLLECTION_GENERATE(INTERVALHEAP, ih1, iheap1, int, int) -CMC_COLLECTION_GENERATE(LINKEDLIST, ll1, linked1, /* K */, int) -CMC_COLLECTION_GENERATE(LIST, l1, list1, /* K */, int) -CMC_COLLECTION_GENERATE(MULTIMAP, mm1, mmap1, int, int) -CMC_COLLECTION_GENERATE(MULTISET, ms1, mset1, /* K */, int) -CMC_COLLECTION_GENERATE(STACK, s1, stack1, /* K */, int) -CMC_COLLECTION_GENERATE(SORTEDLIST, sl1, sotredlist1, /* K */, int) -CMC_COLLECTION_GENERATE(QUEUE, q1, queue1, /* K */, int) -CMC_COLLECTION_GENERATE(TREESET, ts1, tset1, /* K */, int) -CMC_COLLECTION_GENERATE(TREEMAP, tm1, tmap1, int, int) - -CMC_COLLECTION_GENERATE(BIDIMAP, bd2, bidimap2, double, double) -CMC_COLLECTION_GENERATE(DEQUE, d2, deque2, /* K */, double) -CMC_COLLECTION_GENERATE(HASHMAP, hm2, hmap2, double, double) -CMC_COLLECTION_GENERATE(HASHSET, hs2, hset2, /* K */, double) -CMC_COLLECTION_GENERATE(HEAP, h2, heap2, /* K */, double) -CMC_COLLECTION_GENERATE(INTERVALHEAP, ih2, iheap2, double, double) -CMC_COLLECTION_GENERATE(LINKEDLIST, ll2, linked2, /* K */, double) -CMC_COLLECTION_GENERATE(LIST, l2, list2, /* K */, double) -CMC_COLLECTION_GENERATE(MULTIMAP, mm2, mmap2, double, double) -CMC_COLLECTION_GENERATE(MULTISET, ms2, mset2, /* K */, double) -CMC_COLLECTION_GENERATE(STACK, s2, stack2, /* K */, double) -CMC_COLLECTION_GENERATE(SORTEDLIST, sl2, sotredlist2, /* K */, double) -CMC_COLLECTION_GENERATE(QUEUE, q2, queue2, /* K */, double) -CMC_COLLECTION_GENERATE(TREESET, ts2, tset2, /* K */, double) -CMC_COLLECTION_GENERATE(TREEMAP, tm2, tmap2, double, double) - -CMC_COLLECTION_GENERATE(BIDIMAP, bd3, bidimap3, size_t, size_t) -CMC_COLLECTION_GENERATE(DEQUE, d3, deque3, /* K */, size_t) -CMC_COLLECTION_GENERATE(HASHMAP, hm3, hmap3, size_t, size_t) -CMC_COLLECTION_GENERATE(HASHSET, hs3, hset3, /* K */, size_t) -CMC_COLLECTION_GENERATE(HEAP, h3, heap3, /* K */, size_t) -CMC_COLLECTION_GENERATE(INTERVALHEAP, ih3, iheap3, size_t, size_t) -CMC_COLLECTION_GENERATE(LINKEDLIST, ll3, linked3, /* K */, size_t) -CMC_COLLECTION_GENERATE(LIST, l3, list3, /* K */, size_t) -CMC_COLLECTION_GENERATE(MULTIMAP, mm3, mmap3, size_t, size_t) -CMC_COLLECTION_GENERATE(MULTISET, ms3, mset3, /* K */, size_t) -CMC_COLLECTION_GENERATE(STACK, s3, stack3, /* K */, size_t) -CMC_COLLECTION_GENERATE(SORTEDLIST, sl3, sotredlist3, /* K */, size_t) -CMC_COLLECTION_GENERATE(QUEUE, q3, queue3, /* K */, size_t) -CMC_COLLECTION_GENERATE(TREESET, ts3, tset3, /* K */, size_t) -CMC_COLLECTION_GENERATE(TREEMAP, tm3, tmap3, size_t, size_t) - -CMC_COLLECTION_GENERATE(BIDIMAP, bd4, bidimap4, enum app_state, enum app_state) -CMC_COLLECTION_GENERATE(DEQUE, d4, deque4, /* K */, enum app_state) -CMC_COLLECTION_GENERATE(HASHMAP, hm4, hmap4, enum app_state, enum app_state) -CMC_COLLECTION_GENERATE(HASHSET, hs4, hset4, /* K */, enum app_state) -CMC_COLLECTION_GENERATE(HEAP, h4, heap4, /* K */, enum app_state) -CMC_COLLECTION_GENERATE(INTERVALHEAP, ih4, iheap4, enum app_state, enum app_state) -CMC_COLLECTION_GENERATE(LINKEDLIST, ll4, linked4, /* K */, enum app_state) -CMC_COLLECTION_GENERATE(LIST, l4, list4, /* K */, enum app_state) -CMC_COLLECTION_GENERATE(MULTIMAP, mm4, mmap4, enum app_state, enum app_state) -CMC_COLLECTION_GENERATE(MULTISET, ms4, mset4, /* K */, enum app_state) -CMC_COLLECTION_GENERATE(STACK, s4, stack4, /* K */, enum app_state) -CMC_COLLECTION_GENERATE(SORTEDLIST, sl4, sotredlist4, /* K */, enum app_state) -CMC_COLLECTION_GENERATE(QUEUE, q4, queue4, /* K */, enum app_state) -CMC_COLLECTION_GENERATE(TREESET, ts4, tset4, /* K */, enum app_state) -CMC_COLLECTION_GENERATE(TREEMAP, tm4, tmap4, enum app_state, enum app_state) - -CMC_COLLECTION_GENERATE(BIDIMAP, bd5, bidimap5, void *, void *) -CMC_COLLECTION_GENERATE(DEQUE, d5, deque5, /* K */, void *) -CMC_COLLECTION_GENERATE(HASHMAP, hm5, hmap5, void *, void *) -CMC_COLLECTION_GENERATE(HASHSET, hs5, hset5, /* K */, void *) -CMC_COLLECTION_GENERATE(HEAP, h5, heap5, /* K */, void *) -CMC_COLLECTION_GENERATE(INTERVALHEAP, ih5, iheap5, void *, void *) -CMC_COLLECTION_GENERATE(LINKEDLIST, ll5, linked5, /* K */, void *) -CMC_COLLECTION_GENERATE(LIST, l5, list5, /* K */, void *) -CMC_COLLECTION_GENERATE(MULTIMAP, mm5, mmap5, void *, void *) -CMC_COLLECTION_GENERATE(MULTISET, ms5, mset5, /* K */, void *) -CMC_COLLECTION_GENERATE(STACK, s5, stack5, /* K */, void *) -CMC_COLLECTION_GENERATE(SORTEDLIST, sl5, sotredlist5, /* K */, void *) -CMC_COLLECTION_GENERATE(QUEUE, q5, queue5, /* K */, void *) -CMC_COLLECTION_GENERATE(TREESET, ts5, tset5, /* K */, void *) -CMC_COLLECTION_GENERATE(TREEMAP, tm5, tmap5, void *, void *) - -CMC_COLLECTION_GENERATE(BIDIMAP, bd6, bidimap6, int *, int *) -CMC_COLLECTION_GENERATE(DEQUE, d6, deque6, /* K */, int *) -CMC_COLLECTION_GENERATE(HASHMAP, hm6, hmap6, int *, int *) -CMC_COLLECTION_GENERATE(HASHSET, hs6, hset6, /* K */, int *) -CMC_COLLECTION_GENERATE(HEAP, h6, heap6, /* K */, int *) -CMC_COLLECTION_GENERATE(INTERVALHEAP, ih6, iheap6, int *, int *) -CMC_COLLECTION_GENERATE(LINKEDLIST, ll6, linked6, /* K */, int *) -CMC_COLLECTION_GENERATE(LIST, l6, list6, /* K */, int *) -CMC_COLLECTION_GENERATE(MULTIMAP, mm6, mmap6, int *, int *) -CMC_COLLECTION_GENERATE(MULTISET, ms6, mset6, /* K */, int *) -CMC_COLLECTION_GENERATE(STACK, s6, stack6, /* K */, int *) -CMC_COLLECTION_GENERATE(SORTEDLIST, sl6, sotredlist6, /* K */, int *) -CMC_COLLECTION_GENERATE(QUEUE, q6, queue6, /* K */, int *) -CMC_COLLECTION_GENERATE(TREESET, ts6, tset6, /* K */, int *) -CMC_COLLECTION_GENERATE(TREEMAP, tm6, tmap6, int *, int *) - -CMC_COLLECTION_GENERATE(BIDIMAP, bd7, bidimap7, struct imaginary *, struct imaginary *) -CMC_COLLECTION_GENERATE(DEQUE, d7, deque7, /* K */, struct imaginary *) -CMC_COLLECTION_GENERATE(HASHMAP, hm7, hmap7, struct imaginary *, struct imaginary *) -CMC_COLLECTION_GENERATE(HASHSET, hs7, hset7, /* K */, struct imaginary *) -CMC_COLLECTION_GENERATE(HEAP, h7, heap7, /* K */, struct imaginary *) -CMC_COLLECTION_GENERATE(INTERVALHEAP, ih7, iheap7, struct imaginary *, struct imaginary *) -CMC_COLLECTION_GENERATE(LINKEDLIST, ll7, linked7, /* K */, struct imaginary *) -CMC_COLLECTION_GENERATE(LIST, l7, list7, /* K */, struct imaginary *) -CMC_COLLECTION_GENERATE(MULTIMAP, mm7, mmap7, struct imaginary *, struct imaginary *) -CMC_COLLECTION_GENERATE(MULTISET, ms7, mset7, /* K */, struct imaginary *) -CMC_COLLECTION_GENERATE(STACK, s7, stack7, /* K */, struct imaginary *) -CMC_COLLECTION_GENERATE(SORTEDLIST, sl7, sotredlist7, /* K */, struct imaginary *) -CMC_COLLECTION_GENERATE(QUEUE, q7, queue7, /* K */, struct imaginary *) -CMC_COLLECTION_GENERATE(TREESET, ts7, tset7, /* K */, struct imaginary *) -CMC_COLLECTION_GENERATE(TREEMAP, tm7, tmap7, struct imaginary *, struct imaginary *) - -CMC_COLLECTION_GENERATE(BIDIMAP, bd8, bidimap8, double *, double *) -CMC_COLLECTION_GENERATE(DEQUE, d8, deque8, /* K */, double *) -CMC_COLLECTION_GENERATE(HASHMAP, hm8, hmap8, double *, double *) -CMC_COLLECTION_GENERATE(HASHSET, hs8, hset8, /* K */, double *) -CMC_COLLECTION_GENERATE(HEAP, h8, heap8, /* K */, double *) -CMC_COLLECTION_GENERATE(INTERVALHEAP, ih8, iheap8, double *, double *) -CMC_COLLECTION_GENERATE(LINKEDLIST, ll8, linked8, /* K */, double *) -CMC_COLLECTION_GENERATE(LIST, l8, list8, /* K */, double *) -CMC_COLLECTION_GENERATE(MULTIMAP, mm8, mmap8, double *, double *) -CMC_COLLECTION_GENERATE(MULTISET, ms8, mset8, /* K */, double *) -CMC_COLLECTION_GENERATE(STACK, s8, stack8, /* K */, double *) -CMC_COLLECTION_GENERATE(SORTEDLIST, sl8, sotredlist8, /* K */, double *) -CMC_COLLECTION_GENERATE(QUEUE, q8, queue8, /* K */, double *) -CMC_COLLECTION_GENERATE(TREESET, ts8, tset8, /* K */, double *) -CMC_COLLECTION_GENERATE(TREEMAP, tm8, tmap8, double *, double *) - -CMC_COLLECTION_GENERATE(BIDIMAP, bd9, bidimap9, enum app_state *, enum app_state *) -CMC_COLLECTION_GENERATE(DEQUE, d9, deque9, /* K */, enum app_state *) -CMC_COLLECTION_GENERATE(HASHMAP, hm9, hmap9, enum app_state *, enum app_state *) -CMC_COLLECTION_GENERATE(HASHSET, hs9, hset9, /* K */, enum app_state *) -CMC_COLLECTION_GENERATE(HEAP, h9, heap9, /* K */, enum app_state *) -CMC_COLLECTION_GENERATE(INTERVALHEAP, ih9, iheap9, enum app_state *, enum app_state *) -CMC_COLLECTION_GENERATE(LINKEDLIST, ll9, linked9, /* K */, enum app_state *) -CMC_COLLECTION_GENERATE(LIST, l9, list9, /* K */, enum app_state *) -CMC_COLLECTION_GENERATE(MULTIMAP, mm9, mmap9, enum app_state *, enum app_state *) -CMC_COLLECTION_GENERATE(MULTISET, ms9, mset9, /* K */, enum app_state *) -CMC_COLLECTION_GENERATE(STACK, s9, stack9, /* K */, enum app_state *) -CMC_COLLECTION_GENERATE(SORTEDLIST, sl9, sotredlist9, /* K */, enum app_state *) -CMC_COLLECTION_GENERATE(QUEUE, q9, queue9, /* K */, enum app_state *) -CMC_COLLECTION_GENERATE(TREESET, ts9, tset9, /* K */, enum app_state *) -CMC_COLLECTION_GENERATE(TREEMAP, tm9, tmap9, enum app_state *, enum app_state *) diff --git a/benchmarks/maps.c b/benchmarks/maps.c deleted file mode 100644 index 340d354..0000000 --- a/benchmarks/maps.c +++ /dev/null @@ -1,433 +0,0 @@ -#include - -/** - * HashMap, MultiMap and BidiMap use hashtables with different strategies. This - * benchmark is aimed to explore the pros and cons of each implementation. - * - * HashMap - A plain hashtable with no indirection using linear probing and - * robin hood hashing. - * Expectations: - * - Constant memory usage which leads to high memory usage per element - * ratio when the hashtable has few elements but the ratio is - * somewhat good as it starts to fill up; - * - Faster lookup due to no indirection and good caching; - * - Faster insertion and removal due to no calls to free or malloc. - * - * MultiMap - A hashtable using separate chaining where each bucket is a doubly - * linked list. - * Expectations: - * - High memory usage per element ratio due to the double linked - * lists; - * - Pointer indirection might lead to slower lookup and poor caching - * due to using nodes to store the key and the value; - * - A bit slower insertion and removal as calls to free and malloc are - * needed. - * - * BidiMap - Two arrays, one representing the key set and one the value set. - * Each array is made of pointers to an entry. This way one entry can - * be referenced by both the key set and the value set using only one - * node. Uses robin hood hashing to adjust the pointers. - * Expectations: - * - Overrall low memory usage compared to other implementations; - * - Pointer indirection might lead to slower lookupand poor caching - * due to using nodes to store the key and the value; - * - Very slow insertion and removal as a node needs to be added or - * removed on both arrays. - */ - -/* Generate Code */ -CMC_COLLECTION_GENERATE(HASHMAP, hmap, hmap, int, int) -CMC_COLLECTION_GENERATE(MULTIMAP, mmap, mmap, int, int) -CMC_COLLECTION_GENERATE(BIDIMAP, bmap, bmap, int, int) - -/* Forward declaration of benchmarks */ -void benchmark_bidimap(const char *collection, int total_elements, - double load_factor); -void benchmark_hashmap(const char *collection, int total_elements, - double load_factor); -void benchmark_multimap(const char *collection, int total_elements, - double load_factor); - -/* Comparator and Hash function */ -int cmp(int a, int b) -{ - return a - b; -} - -size_t hash(int a) -{ - size_t x = (size_t)a; - x = ((x >> 16) ^ x) * 0x45d9f3b; - x = ((x >> 16) ^ x) * 0x45d9f3b; - x = (x >> 16) ^ x; - return x; -} - -/* Custom allocators to count memory usage */ -size_t total_memory = 0; - -/* Report Functions */ -void print_overview(const char *collection, int total_elements, - double load_factor) -{ - printf("Overview\n" - " Collection : %s\n" - " Total Elements : %d\n" - " Load Factor : %.4lf\n\n", - collection, total_elements, load_factor); -} - -void print_time(const char *collection, double C, double R, double U, double D) -{ - /* C - Create, R - Read, U - Update, D - Delete */ - printf("Time [%s]: \n" - " Total : %8.0lf milliseconds \n" - " Create : %8.0lf milliseconds\n" - " Read : %8.0lf milliseconds\n" - " Update : %8.0lf milliseconds\n" - " Delete : %8.0lf milliseconds\n\n", - collection, C + R + U + D, C, R, U, D); -} - -void print_memory(const char *s, size_t memory[11], int partition_size) -{ - printf("Each Partition : %d elements\n\n", partition_size); - - for (size_t i = 0; i < 11; i++) - { - printf(" %3" PRIuMAX "%% : %12" PRIuMAX " B | %10" PRIuMAX " kB | %8" PRIuMAX " MB (+ %2.0lf%%)\n", - i * 10, memory[i], memory[i] / 1000, memory[i] / 1000000, (1 - ((double)memory[0] / (double)memory[i])) * 100.0); - } -} - -/* Custom allocation functions */ -void *my_malloc(size_t size) -{ - void *result = malloc(size); - - if (result) - total_memory += size; - - return result; -} - -void *my_calloc(size_t count, size_t size) -{ - void *result = calloc(count, size); - - if (result) - total_memory += count * size; - - return result; -} - -void *my_realloc(void *buffer, size_t size) -{ - /* This assumes that this benchmark never uses realloc */ - return realloc(buffer, size); -} - -void my_free(void *block) -{ - free(block); -} - -/* Default custom allocation node */ -struct cmc_alloc_node alloc_default = { .malloc = my_malloc, - .calloc = my_calloc, - .realloc = my_realloc, - .free = my_free }; - -int main(int argc, char const *argv[]) -{ - if (argc != 4) - { - fprintf( - stderr, - "Usage:\n" - " %s collection_name total_elements load_factor\n" - "\nOPTIONS\n" - " - collection_name : (BIDIMAP|HASHMAP|MULTIMAP|ALL)\n" - " - total_elements : Total elements to be added to the hashtable (int > 0)\n" - " - load_factor : The hashtable's load factor (0 < l < 1.0)\n", - argv[0]); - return 1; - } - - int total_elements = atoi(argv[2]); - double load_factor = atof(argv[3]); - - bool error = false; - - if (total_elements < 1) - { - error = true; - fprintf(stderr, "Invalid value for total_elements: %s\n", argv[2]); - } - - if (load_factor <= 0.0 || load_factor >= 1.0) - { - error = true; - fprintf(stderr, "Invalid value for load_factor: %s\n", argv[3]); - } - - if (error) - return 1; - - const char *collection = argv[1]; - - if (strcmp(collection, "BIDIMAP") == 0) - { - benchmark_bidimap(collection, total_elements, load_factor); - } - else if (strcmp(collection, "HASHMAP") == 0) - { - benchmark_hashmap(collection, total_elements, load_factor); - } - else if (strcmp(collection, "MULTIMAP") == 0) - { - benchmark_multimap(collection, total_elements, load_factor); - } - else if (strcmp(collection, "ALL") == 0) - { - benchmark_bidimap("BIDIMAP", total_elements, load_factor); - benchmark_hashmap("HASHMAP", total_elements, load_factor); - benchmark_multimap("MULTIMAP", total_elements, load_factor); - } - else - { - fprintf(stderr, "Unknown parameter collection_name = %s\n", collection); - return 1; - } - - return 0; -} - -void benchmark_bidimap(const char *collection, int total_elements, - double load_factor) -{ - printf("--------------------------------------------------------------------------------\n"); - - total_memory = 0; - - /* Normalize total_elements to be a multiple of 10 and calculate partition size */ - total_elements = total_elements % 10 == 0 ? total_elements : total_elements + (10 - total_elements % 10); - int partition = total_elements / 10; - - print_overview(collection, total_elements, load_factor); - - struct bmap *map = bmap_new_custom(total_elements, load_factor, cmp, hash, - cmp, hash, &alloc_default, NULL); - - /* Create, Read, Update, Delete */ - struct cmc_timer timers[4] = { 0 }; - - /* Memory Usage 0%, 10%, 20%, ... 100% */ - size_t memory[11] = {0}; - - memory[0] = total_memory; - - /* Create */ - cmc_timer_start(timers[0]); - for (int i = 0; i < 10; i++) - { - for (int j = partition * i; j < partition * (i + 1); j++) - { - bmap_insert(map, j, j); - } - - memory[i + 1] = total_memory; - } - - cmc_timer_stop(timers[0]); - cmc_timer_calc(timers[0]); - /* Create End */ - - /* Read */ - cmc_timer_start(timers[1]); - for (int i = 0; i < total_elements; i++) - bmap_contains_key(map, i); - - cmc_timer_stop(timers[1]); - cmc_timer_calc(timers[1]); - /* Read End */ - - /* Update */ - cmc_timer_start(timers[2]); - for (int i = 0; i < total_elements; i++) - bmap_update_val_by_key(map, i, total_elements - i - 1); - - cmc_timer_stop(timers[2]); - cmc_timer_calc(timers[2]); - /* Update End */ - - /* Delete */ - cmc_timer_start(timers[3]); - for (int i = 0; i < total_elements; i++) - bmap_remove_by_key(map, i, NULL, NULL); - - cmc_timer_stop(timers[3]); - cmc_timer_calc(timers[3]); - /* Delete End */ - - print_time(collection, timers[0].result, timers[1].result, timers[2].result, - timers[3].result); - - print_memory(collection, memory, partition); - - bmap_free(map, NULL); - - printf("--------------------------------------------------------------------------------\n"); -} - -void benchmark_hashmap(const char *collection, int total_elements, - double load_factor) -{ - printf("--------------------------------------------------------------------------------\n"); - - total_memory = 0; - - /* Normalize total_elements to be a multiple of 10 and calculate partition size */ - total_elements = total_elements % 10 == 0 ? total_elements : total_elements + (10 - total_elements % 10); - int partition = total_elements / 10; - - print_overview(collection, total_elements, load_factor); - - struct hmap *map = hmap_new_custom(total_elements, load_factor, cmp, hash, &alloc_default, NULL); - - /* Create, Read, Update, Delete */ - struct cmc_timer timers[4] = { 0 }; - - /* Memory Usage 0%, 10%, 20%, ... 100% */ - size_t memory[11] = {0}; - - memory[0] = total_memory; - - /* Create */ - cmc_timer_start(timers[0]); - for (int i = 0; i < 10; i++) - { - for (int j = partition * i; j < partition * (i + 1); j++) - { - hmap_insert(map, j, j); - } - - memory[i + 1] = total_memory; - } - - cmc_timer_stop(timers[0]); - cmc_timer_calc(timers[0]); - /* Create End */ - - /* Read */ - cmc_timer_start(timers[1]); - for (int i = 0; i < total_elements; i++) - hmap_contains(map, i); - - cmc_timer_stop(timers[1]); - cmc_timer_calc(timers[1]); - /* Read End */ - - /* Update */ - cmc_timer_start(timers[2]); - for (int i = 0; i < total_elements; i++) - hmap_update(map, i, total_elements - i - 1, NULL); - - cmc_timer_stop(timers[2]); - cmc_timer_calc(timers[2]); - /* Update End */ - - /* Delete */ - cmc_timer_start(timers[3]); - for (int i = 0; i < total_elements; i++) - hmap_remove(map, i, NULL); - - cmc_timer_stop(timers[3]); - cmc_timer_calc(timers[3]); - /* Delete End */ - - print_time(collection, timers[0].result, timers[1].result, timers[2].result, - timers[3].result); - - print_memory(collection, memory, partition); - - hmap_free(map, NULL); - - printf("--------------------------------------------------------------------------------\n"); -} - -void benchmark_multimap(const char *collection, int total_elements, - double load_factor) -{ - printf("--------------------------------------------------------------------------------\n"); - - total_memory = 0; - - /* Normalize total_elements to be a multiple of 10 and calculate partition size */ - total_elements = total_elements % 10 == 0 ? total_elements : total_elements + (10 - total_elements % 10); - int partition = total_elements / 10; - - print_overview(collection, total_elements, load_factor); - - struct mmap *map = mmap_new_custom(total_elements, load_factor, cmp, hash, &alloc_default, NULL); - - /* Create, Read, Update, Delete */ - struct cmc_timer timers[4] = { 0 }; - - /* Memory Usage 0%, 10%, 20%, ... 100% */ - size_t memory[11] = {0}; - - memory[0] = total_memory; - - /* Create */ - cmc_timer_start(timers[0]); - for (int i = 0; i < 10; i++) - { - for (int j = partition * i; j < partition * (i + 1); j++) - { - mmap_insert(map, j, j); - } - - memory[i + 1] = total_memory; - } - - cmc_timer_stop(timers[0]); - cmc_timer_calc(timers[0]); - /* Create End */ - - /* Read */ - cmc_timer_start(timers[1]); - for (int i = 0; i < total_elements; i++) - mmap_contains(map, i); - - cmc_timer_stop(timers[1]); - cmc_timer_calc(timers[1]); - /* Read End */ - - /* Update */ - cmc_timer_start(timers[2]); - for (int i = 0; i < total_elements; i++) - mmap_update(map, i, total_elements - i - 1, NULL); - - cmc_timer_stop(timers[2]); - cmc_timer_calc(timers[2]); - /* Update End */ - - /* Delete */ - cmc_timer_start(timers[3]); - for (int i = 0; i < total_elements; i++) - mmap_remove(map, i, NULL); - - cmc_timer_stop(timers[3]); - cmc_timer_calc(timers[3]); - /* Delete End */ - - print_time(collection, timers[0].result, timers[1].result, timers[2].result, - timers[3].result); - - print_memory(collection, memory, partition); - - mmap_free(map, NULL); - - printf("--------------------------------------------------------------------------------\n"); -} diff --git a/benchmarks/queue/Makefile b/benchmarks/queue/Makefile deleted file mode 100644 index c3ee3f9..0000000 --- a/benchmarks/queue/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -CFLAGS = -Wall -Wextra -INCLUDE = ../../src - -main: - gcc queue.c -I $(INCLUDE) $(CFLAGS) -o a.exe -DCMC_QUEUE - a.exe - gcc queue.c -I $(INCLUDE) $(CFLAGS) -o a.exe -DSAC_QUEUE - a.exe diff --git a/benchmarks/queue/queue.c b/benchmarks/queue/queue.c deleted file mode 100644 index 8d74a1f..0000000 --- a/benchmarks/queue/queue.c +++ /dev/null @@ -1,76 +0,0 @@ -/** - * queue.c - * - * Creation Date: 24/06/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -/* Showing off how different queue implementations affect runtime cost */ - -#include "utl/timer.h" -#include -#include - -#define MAX 200000 - -#if defined(CMC_QUEUE) -#include "cmc/queue.h" -CMC_GENERATE_QUEUE(q, queue, int) -#define TARGET "QUEUE" -#elif defined(SAC_QUEUE) -#include "sac/queue.h" -SAC_QUEUE_GENERATE(q, queue, , int, MAX) -#define TARGET "SAC QUEUE" -#else -#error Please define either CMC_QUEUE, SAC_QUEUE or EXT_QUEUE -#endif - -int main(void) -{ - -#if defined(CMC_QUEUE) - struct queue *q = q_new(MAX); -#elif defined(SAC_QUEUE) - queue _q = q_new(); - queue_ptr q = &_q; -#endif - - size_t sum = 0; - int i = 0; - - struct cmc_timer timer; - cmc_timer_start(timer); - - while (q_count(q) != MAX) - { - q_enqueue(q, i++); - - if (i % 10 == 0) - { - for (size_t i = 0; i < 9; i++) - { - sum += q_peek(q); - q_dequeue(q); - } - } - - } - - cmc_timer_stop(timer); - cmc_timer_calc(timer); - - printf("----------------------------------------\n"); - printf("%s\n", TARGET); - printf("Execution time: %.0lf milliseconds\n", timer.result); - printf("SUM: %" PRIuMAX "\n", sum); - printf("----------------------------------------\n"); - -#if defined(CMC_QUEUE) - q_free(q, NULL); -#endif - - return 0; -} diff --git a/benchmarks/util/twister.c b/benchmarks/util/twister.c deleted file mode 100644 index bd9b8a3..0000000 --- a/benchmarks/util/twister.c +++ /dev/null @@ -1,102 +0,0 @@ -/** - * twister.c - * - * Creation Date: 09/05/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - * Mersenne Twister PRNG utility - * - */ -#include -#include -#include - -#define NN 312 -#define MM 156 -#define MATRIX_A UINT64_C(0xB5026F5AA96619E9) -#define UM UINT64_C(0xFFFFFFFF80000000) // Most significant 33 bits -#define LM UINT64_C(0x7FFFFFFF) // Least significant 31 bits - -// State vector -typedef struct mt_state_s -{ - uint64_t mt[NN]; - int mti; -} mt_state, *mt_state_ptr; - -// Initializes mt[NN] with a seed -void twist_init(mt_state_ptr st, uint64_t seed); - -// Generates a random uint64_t in [0, 2^64-1] interval -uint64_t twist_uint64(mt_state_ptr st); - -// Generates a double in [0, 1) interval -double twist_real(mt_state_ptr st); - -// -// Implementation -// - -// Initialize a state mt[NN] with a seed -void twist_init(mt_state_ptr st, uint64_t seed) -{ - st->mti = NN + 1; - - st->mt[0] = seed; - - for (st->mti = 1; st->mti < NN; st->mti++) - { - st->mt[st->mti] = (UINT64_C(6364136223846793005) * (st->mt[st->mti - 1] ^ (st->mt[st->mti - 1] >> 62)) + st->mti); - } -} - -// Generates a random uint64_t in [0, 2^64-1] interval -uint64_t twist_uint64(mt_state_ptr st) -{ - int i; - uint64_t x; - static uint64_t mag01[2] = {UINT64_C(0), MATRIX_A}; - - if (st->mti >= NN) - { - // Generate NN words at one time if twist_init() has not been called - // A default initial seed is used - if (st->mti == NN + 1) - twist_init(st, UINT64_C(5489)); - - for (i = 0; i < NN - MM; i++) - { - x = (st->mt[i] & UM) | (st->mt[i + 1] & LM); - st->mt[i] = st->mt[i + MM] ^ (x >> 1) ^ mag01[(int)(x & UINT64_C(1))]; - } - - for (; i < NN - 1; i++) - { - x = (st->mt[i] & UM) | (st->mt[i + 1] & LM); - st->mt[i] = st->mt[i + (MM - NN)] ^ (x >> 1) ^ mag01[(int)(x & UINT64_C(1))]; - } - - x = (st->mt[NN - 1] & UM) | (st->mt[0] & LM); - - st->mt[NN - 1] = st->mt[MM - 1] ^ (x >> 1) ^ mag01[(int)(x & UINT64_C(1))]; - - st->mti = 0; - } - - x = st->mt[st->mti++]; - - x ^= (x >> 29) & UINT64_C(0x5555555555555555); - x ^= (x << 17) & UINT64_C(0x71D67FFFEDA60000); - x ^= (x << 37) & UINT64_C(0xFFF7EEE000000000); - x ^= (x >> 43); - - return x; -} - -// Generates a double in [0, 1) interval -double twist_real(mt_state_ptr st) -{ - return (twist_uint64(st) >> 11) * (1.0 / 9007199254740992.0); -} diff --git a/examples/README.md b/examples/README.md deleted file mode 100644 index 3ebd653..0000000 --- a/examples/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# Examples - -* deque - DEQUE collection examples -* hashmap - HASHMAP collection examples -* hashset - HASHSET collection examples -* heap - HEAP collection examples -* iterators - Examples of using the collection's iterators -* linkedlist - LINKEDLIST collection examples -* list - LIST collection examples -* multimap - MULTIMAP collection examples -* multiset - MULTISET collection examples -* others - Other examples, generally more robust and using multiple collections -* queue - QUEUE collection examples -* stack - STACK collection examples -* treemap - TREEMAP collection examples -* treeset - TREESET collection examples diff --git a/examples/deque/README.md b/examples/deque/README.md deleted file mode 100644 index ab0098f..0000000 --- a/examples/deque/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Deque examples - -* even_odd.c - separates odd numbers to one end of the deque and even number to the other. Sum only half of it to give the total sum of even numbers. -* iterator.c - A complete example of the deque iterator diff --git a/examples/deque/even_odd.c b/examples/deque/even_odd.c deleted file mode 100644 index 1a741b1..0000000 --- a/examples/deque/even_odd.c +++ /dev/null @@ -1,54 +0,0 @@ -/** - * even_odd.c - * - * Creation Date: 03/04/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ -#include "cmc/deque.h" -#include -#include -#include - -CMC_GENERATE_DEQUE(d, deque, size_t); -typedef struct deque deque; -typedef struct deque_iter deque_iter; - -int main(int argc, char const *argv[]) -{ - // 1- Add odd numbers to the start of the deque and even numbers to the end. - // 2- Iterate over the deque, starting from the end, until index is half - // the deque count and stop. - // 3- Sum of all even numbers - - deque *numbers = d_new(1000); - - for (size_t i = 1; i <= 100000; i++) - { - i % 2 == 0 ? d_push_back(numbers, i) : d_push_front(numbers, i); - } - - deque_iter iter; - d_iter_init(&iter, numbers); - - size_t result, index, sum = 0; - - for (d_iter_to_end(&iter); !d_iter_start(&iter); d_iter_prev(&iter)) - { - result = d_iter_value(&iter); - index = d_iter_index(&iter); - - if ((double)index < (double)d_count(numbers) / 2.0) - break; - - sum += result; - } - - printf("Total sum: %lu\n", sum); - - assert(sum == 2500050000); - - return 0; -} diff --git a/examples/deque/iterator.c b/examples/deque/iterator.c deleted file mode 100644 index 6c49785..0000000 --- a/examples/deque/iterator.c +++ /dev/null @@ -1,201 +0,0 @@ -/** - * iterator.c - * - * Creation Date: 13/05/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - * Iterator Example - */ -#include "cmc/deque.h" -#include -#include - -// Creates a deque of integers -CMC_GENERATE_DEQUE(d, deque, size_t); -typedef struct deque deque; -typedef struct deque_iter deque_iter; - -int main(int argc, char const *argv[]) -{ - // Create a new deque with an initial capacity of 100 - deque *my_deque = d_new(100); - - // Add elements to the deque - for (int i = 0; i < 20; i++) - { - // Add odd numbers to the front, even numbers to the back. - if (i % 2 == 0) - d_push_front(my_deque, i); - else - d_push_back(my_deque, i); - } - - // Iterate from the start (front index) to the end (rear index) of the deque - for (deque_iter it = my_deque->it_start(my_deque); // Initialize iterator 'it' to the start of the deque - !d_iter_end(&it); // Conditional stop (until it is not at the end) - d_iter_next(&it)) // Iterator goes one position forward - { - // Access the current element - int e = d_iter_value(&it); - - // Access the current index (index is relative to all the elements in the iteration) - size_t i = d_iter_index(&it); - - // Print deque - - // Index is useful in situations like this - // If it is the first element - if (i == 0) - printf("[ %d, ", e); - // If it is the last element - else if (i == d_count(my_deque) - 1) - printf("%d ]\n", e); - // For elements at the middle - else - printf("%d, ", e); - } - - // Index can also be used to iterate over a certain portion of a collection - size_t limit = d_count(my_deque) / 2; - for (deque_iter it = my_deque->it_start(my_deque); !d_iter_end(&it); d_iter_next(&it)) - { - // Access the current element - int e = d_iter_value(&it); - - // Access the current index (index is relative to all the elements in the iteration) - size_t i = d_iter_index(&it); - - // Print deque up until limit - - // If it is the first element - if (i == 0) - printf("[ %d, ", e); - // If it is the last element - else if (i == limit - 1) // -1 because index is 0 based and we want half of the deque - { - printf("%d ]\n", e); - break; - } - // For elements at the middle - else - printf("%d, ", e); - } - - // Going backwards - for (deque_iter it = my_deque->it_end(my_deque); // Initialize iterator 'it' to the end of the deque - !d_iter_start(&it); // Conditional stop (until it is not at the start) - d_iter_prev(&it)) // Iterator goes one position backwards - { - // Access the current element - int e = d_iter_value(&it); - - // Access the current index (index is relative to all the elements in the iteration) - size_t i = d_iter_index(&it); - - // Print deque - // Note how the conditions for the first and last elements are simply swapped - // Because iterating backwards make the first element be the index count - 1 - // and the last one be the index 0 - - // If it is the first element - if (i == d_count(my_deque) - 1) - printf("[ %d, ", e); - // If it is the last element - else if (i == 0) - printf("%d ]\n", e); - // For elements at the middle - else - printf("%d, ", e); - } - - // You can also use iterators in a while loop - // But to do so you must declare the iterator struct outside the loop first - deque_iter it; - - // You have three options: - // - Initialize it using the functions provided by the deque [ my_deque->it_start() and my_deque->it_end() ] - // - Initialize it using the init() function (when the iterator is already allocated) - // - Initialize it using the new() function (allocates on the heap, pointers only) - - it = my_deque->it_start(my_deque); - it = my_deque->it_end(my_deque); - - // This is equivalent to it_start() - d_iter_init(&it, my_deque); - - // For pointers - // Also equivalent to it_start() - deque_iter *iter = d_iter_new(my_deque); - - // The actual while loop - while (!d_iter_end(iter)) - { - // Accessing elements - int e = d_iter_value(iter); - size_t i = d_iter_index(iter); - - // Print index and element - printf("deque[%2" PRIuMAX "] = %2d\n", i, e); - - // Move iterator forwards - d_iter_next(iter); - } - - // Send the iterator to the start of the deque - d_iter_to_start(iter); - - // Send the iterator to the end of the deque - d_iter_to_end(iter); - - // Backwards loop - while (!d_iter_start(iter)) - { - // Accessing elements - int e = d_iter_value(iter); - size_t i = d_iter_index(iter); - - // Print index and element - printf("deque[%2" PRIuMAX "] = %2d\n", i, e); - - // Move iterator backwards - d_iter_prev(iter); - } - - // Certain iterators also allow you to modify the contents it is iterating over - // Exceptions are collections that depend of the current state of the element - // like tree-based collections and heap (collections that have some kind of ordering). - // You also can't change the keys of an associative collection - - // Change every element that is divisible by 3 to the number 7 - for (d_iter_to_start(&it); !d_iter_end(&it); d_iter_next(&it)) - { - // Get a reference to the current value - size_t *r = d_iter_rvalue(&it); - - if (r != NULL && *r % 3 == 0) - *r = 7; - } - - // Now print it to see the difference - for (deque_iter it = my_deque->it_start(my_deque); !d_iter_end(&it); d_iter_next(&it)) - { - int e = d_iter_value(&it); - size_t i = d_iter_index(&it); - - if (i == 0) - printf("[ %d, ", e); - else if (i == d_count(my_deque) - 1) - printf("%d ]\n", e); - else - printf("%d, ", e); - } - - // Dispose the iterator called by d_iter_new() - d_iter_free(iter); - // Dispose the deque created - d_free(my_deque, NULL); - - return 0; -} diff --git a/examples/dfs.c b/examples/dfs.c deleted file mode 100644 index 9bb181a..0000000 --- a/examples/dfs.c +++ /dev/null @@ -1,87 +0,0 @@ -/** - * Example of In-Order Depth-First Search using: - * - A Stack - * - Recursion - * - Without both - */ - -#define CMC_CAMEL_CASE - -#include "macro_collections.h" - -C_MACRO_COLLECTIONS_GEN(CMC, TREESET, (tree, BinaryTree, , , int32_t), (ITER, STR)) - -#define MYSTACK (stk, Stack, , , struct BinaryTreeNode *) - -C_MACRO_COLLECTIONS(CMC, STACK, CORE, STRUCT, MYSTACK) -C_MACRO_COLLECTIONS(CMC, STACK, CORE, HEADER, MYSTACK) -C_MACRO_COLLECTIONS(CMC, STACK, CORE, SOURCE, MYSTACK) - -void DFS(struct BinaryTreeNode *root) -{ - if (!root) - return; - - DFS(root->left); - - fprintf(stdout, "%d ", root->value); - - DFS(root->right); -} - -int main(void) -{ - struct BinaryTree *tree = tree_new(&(struct BinaryTreeFVal){ .cmp = cmc_i32_cmp, .str = cmc_i32_str, NULL }); - - for (int i = 1; i <= 10; i++) - tree_insert(tree, i); - - int32_t result = 1; - - cmc_assert(tree_min(tree, &result)); - cmc_assert_equals(int32_t, 1, result); - - cmc_assert(tree_max(tree, &result)); - cmc_assert_equals(int32_t, 10, result); - - printf("Without Recursion or Stack:\n"); - tree_print(tree, stdout, "[ ", " ", " ]\n"); - - printf("Recursion:\n"); - fprintf(stdout, "[ "); - DFS(tree->root); - fprintf(stdout, "]\n"); - - printf("Stack:\n"); - fprintf(stdout, "[ "); - struct Stack *stack = stk_new(100, &(struct StackFVal){ NULL }); - - struct BinaryTreeNode *node = tree->root; - - while (node || !stk_empty(stack)) - { - if (node) - { - if (!stk_push(stack, node)) - cmc_log_error("Could not push to stack %d\n", cmc_flags_to_str[stk_flag(stack)]); - - node = node->left; - } - else - { - node = stk_top(stack); - - if (!stk_pop(stack)) - cmc_log_error("Could not pop from the stack %s\n", cmc_flags_to_str[stk_flag(stack)]); - - fprintf(stdout, "%d ", node->value); - - node = node->right; - } - } - - stk_free(stack); - fprintf(stdout, "]\n"); - - tree_free(tree); -} diff --git a/examples/example.c b/examples/example.c deleted file mode 100644 index bf1ca90..0000000 --- a/examples/example.c +++ /dev/null @@ -1,67 +0,0 @@ -// This is the master header. This will include every feature of the library. -// This comes with many helper macros (high level API) and utility functions. -#include "macro_collections.h" - -// A PARAM is a standard way to pass required parameters to the lower level API. -// It is a tuple of form (PFX, SNAME, SIZE, K, V). In this case, not all of them -// are used, so we can leave them empty. We are creating a list of value int. -#define MY_LIST_PARAMS (intl, int_list, , , int) - -// High level API. Generate a LIST from the CMC library with the STR extension -// using our previously defined PARAMs. Every collections has a CORE part that -// needs to be generated first. Then, we can add other parts after. This macro -// does all of that for us. The STR part will provide us with a function that -// will be used later. -C_MACRO_COLLECTIONS_EXTENDED(CMC, LIST, MY_LIST_PARAMS, (STR)) - -int main(void) -{ - // Our list type is defined by SNAME and all functions are prefixed by PFX - // (PFX can also be thought as the function's namespace). Also, nodes, - // entries, iterators and other structures are prefixed by SNAME. So PFX is - // for functions and SNAME is for structs, where the main one is simply - // 'struct SNAME'. - // To initialize a list we need to pass in an initial capacity and something - // that is called a function table for the V type. - // This function table is a struct with methods that will extract some - // (sometimes) necessary behaviour from your custom data type. Things like - // hash, comparison and printing. A list doesn't require any of these - // functions. That is, the CORE module doesn't use any of them. - // But since we are using the STR module, we will need to define the 'str' - // function. luckily, for the 'int' type, the library already provides such - // function (cmc_i32_str), provided by the /utl/futils.h header file. - struct int_list *list = intl_new(32, &(struct int_list_fval){ .str = cmc_i32_str, NULL }); - - // Check if the list was successfully initialized. It could fail if the - // initial capacity is too big or if 'struct int_list_fval *' is NULL, - // because every data structure must have a valid function table. - if (!list) - return 1; - - // Add some items to the list. The CMC data structures are all dynamically - // sized. So there can be as many items as you want as long as you have - // enough memory. - for (int i = 0; i < 100; i++) - { - // Try to add an element to the list. If it fails you can check what - // caused it by getting its flag. - if (!intl_push_back(list, i)) - { - enum cmc_flags flag = intl_flag(list); - // Use cmc_flags_to_str to map the enum error to a string. - fprintf(stderr, "%s : push_back failed\n", cmc_flags_to_str[flag]); - } - } - - // Now we will use the STR module, the _print() function. This is where the - // '.str' from the function table comes into play. If we haven't defined it, - // the program would've crashed. We also need to define to which file we - // will be printing the list's content. In this case, the terminal. Also, - // some strings need to be defined. They will be printed: before all elements, - // between each one, and after all elements. This is very usefull and can - // print a data structure very nicely. - intl_print(list, stdout, "[ ", ", ", " ]\n"); - - // Free all of its resources - intl_free(list); -} diff --git a/examples/hanoi.c b/examples/hanoi.c deleted file mode 100644 index e4053b0..0000000 --- a/examples/hanoi.c +++ /dev/null @@ -1,73 +0,0 @@ -#include "macro_collections.h" - -#define MYSTACK (stk, stack, , , int) - -C_MACRO_COLLECTIONS(CMC, STACK, CORE, STRUCT, MYSTACK) -C_MACRO_COLLECTIONS(CMC, STACK, CORE, HEADER, MYSTACK) -C_MACRO_COLLECTIONS(CMC, STACK, CORE, SOURCE, MYSTACK) - -struct -{ - struct stack *from; - struct stack *aux; - struct stack *to; -} print_aux = { NULL }; - -void print_stacks() -{ - for (int i = 9; i >= 0; i--) - { - int ia = print_aux.from->buffer[i]; - int ib = print_aux.aux->buffer[i]; - int ic = print_aux.to->buffer[i]; - - printf("| %c | %c | %c |\n", ia == 0 ? 32 : ia + 48, ib == 0 ? 32 : ib + 48, ic == 0 ? 32 : ic + 48); - } - - printf("+---+---+---+\n\n"); -} - -void move(struct stack *from, struct stack *to) -{ - stk_push(to, stk_top(from)); - - stk_pop(from); -} - -void hanoi(int n, struct stack *from, struct stack *aux, struct stack *to) -{ - if (n == 0) - return; - - hanoi(n - 1, from, to, aux); - - move(from, to); - - print_stacks(); - - hanoi(n - 1, aux, from, to); -} - -int main(int argc, char const *argv[]) -{ - struct stack *from = stk_new(10, &(struct stack_fval){ NULL }); - struct stack *to = stk_new(10, &(struct stack_fval){ NULL }); - struct stack *aux = stk_new(10, &(struct stack_fval){ NULL }); - - for (int i = 4; i >= 1; i--) - stk_push(from, i); - - print_aux.from = from; - print_aux.aux = aux; - print_aux.to = to; - - print_stacks(); - - hanoi(stk_count(from), from, aux, to); - - stk_free(from); - stk_free(to); - stk_free(aux); - - return 0; -} diff --git a/examples/hashmap/README.md b/examples/hashmap/README.md deleted file mode 100644 index 19acaf6..0000000 --- a/examples/hashmap/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Hashmap examples - -* countries - Uses a hashmap to map the country name to its population -* foreach.c - ForEach macro example -* iterator.c - A complete example of the hashmap iterator diff --git a/examples/hashmap/countries/data.csv b/examples/hashmap/countries/data.csv deleted file mode 100644 index 5146c12..0000000 --- a/examples/hashmap/countries/data.csv +++ /dev/null @@ -1,216 +0,0 @@ -Afghanistan,34656032 -Albania,2876101 -Algeria,40606052 -American Samoa,55599 -Andorra,77281 -Angola,28813463 -Antigua and Barbuda,100963 -Argentina,43847430 -Armenia,2924816 -Aruba,104822 -Australia,24127159 -Austria,8747358 -Azerbaijan,9762274 -Bahamas; The,391232 -Bahrain,1425171 -Bangladesh,162951560 -Barbados,284996 -Belarus,9507120 -Belgium,11348159 -Belize,366954 -Benin,10872298 -Bermuda,65331 -Bhutan,797765 -Bolivia,10887882 -Bosnia and Herzegovina,3516816 -Botswana,2250260 -Brazil,207652865 -British Virgin Islands,30661 -Brunei Darussalam,423196 -Bulgaria,7127822 -Burkina Faso,18646433 -Burundi,10524117 -Cabo Verde,539560 -Cambodia,15762370 -Cameroon,23439189 -Canada,36286425 -Cayman Islands,60765 -Central African Republic,4594621 -Chad,14452543 -Channel Islands,164541 -Chile,17909754 -China,1378665000 -Colombia,48653419 -Comoros,795601 -Congo; Dem. Rep.,78736153 -Congo; Rep.,5125821 -Costa Rica,4857274 -Cote d'Ivoire,23695919 -Croatia,4170600 -Cuba,11475982 -Curacao,159999 -Cyprus,1170125 -Czech Republic,10561633 -Denmark,5731118 -Djibouti,942333 -Dominica,73543 -Dominican Republic,10648791 -Ecuador,16385068 -Egypt; Arab Rep.,95688681 -El Salvador,6344722 -Equatorial Guinea,1221490 -Estonia,1316481 -Ethiopia,102403196 -Faroe Islands,49117 -Fiji,898760 -Finland,5495096 -France,66896109 -French Polynesia,280208 -Gabon,1979786 -Gambia; The,2038501 -Georgia,3719300 -Germany,82667685 -Ghana,28206728 -Gibraltar,34408 -Greece,10746740 -Greenland,56186 -Grenada,107317 -Guam,162896 -Guatemala,16582469 -Guinea,12395924 -Guinea-Bissau,1815698 -Guyana,773303 -Haiti,10847334 -Honduras,9112867 -Hong Kong SAR; China,7346700 -Hungary,9817958 -Iceland,334252 -India,1324171354 -Indonesia,261115456 -Iran; Islamic Rep.,80277428 -Iraq,37202572 -Ireland,4773095 -Isle of Man,83737 -Israel,8547100 -Italy,60600590 -Jamaica,2881355 -Japan,126994511 -Jordan,9455802 -Kazakhstan,17797032 -Kenya,48461567 -Kiribati,114395 -Korea; Dem. People’s Rep.,25368620 -Korea; Rep.,51245707 -Kosovo,1816200 -Kuwait,4052584 -Kyrgyz Republic,6082700 -Lao PDR,6758353 -Latvia,1960424 -Lebanon,6006668 -Lesotho,2203821 -Liberia,4613823 -Libya,6293253 -Liechtenstein,37666 -Lithuania,2872298 -Luxembourg,582972 -Macao SAR; China,612167 -Macedonia; FYR,2081206 -Madagascar,24894551 -Malawi,18091575 -Malaysia,31187265 -Maldives,417492 -Mali,17994837 -Malta,436947 -Marshall Islands,53066 -Mauritania,4301018 -Mauritius,1263473 -Mexico,127540423 -Micronesia; Fed. Sts.,104937 -Moldova,3552000 -Monaco,38499 -Mongolia,3027398 -Montenegro,622781 -Morocco,35276786 -Mozambique,28829476 -Myanmar,52885223 -Namibia,2479713 -Nauru,13049 -Nepal,28982771 -Netherlands,17018408 -New Caledonia,278000 -New Zealand,4692700 -Nicaragua,6149928 -Niger,20672987 -Nigeria,185989640 -Northern Mariana Islands,55023 -Norway,5232929 -Oman,4424762 -Pakistan,193203476 -Palau,21503 -Panama,4034119 -Papua New Guinea,8084991 -Paraguay,6725308 -Peru,31773839 -Philippines,103320222 -Poland,37948016 -Portugal,10324611 -Puerto Rico,3411307 -Qatar,2569804 -Romania,19705301 -Russian Federation,144342396 -Rwanda,11917508 -Samoa,195125 -San Marino,33203 -Sao Tome and Principe,199910 -Saudi Arabia,32275687 -Senegal,15411614 -Serbia,7057412 -Seychelles,94677 -Sierra Leone,7396190 -Singapore,5607283 -Sint Maarten (Dutch part),40005 -Slovak Republic,5428704 -Slovenia,2064845 -Solomon Islands,599419 -Somalia,14317996 -South Africa,55908865 -South Sudan,12230730 -Spain,46443959 -Sri Lanka,21203000 -St. Kitts and Nevis,54821 -St. Lucia,178015 -St. Martin (French part),31949 -St. Vincent and the Grenadines,109643 -Sudan,39578828 -Suriname,558368 -Swaziland,1343098 -Sweden,9903122 -Switzerland,8372098 -Syrian Arab Republic,18430453 -Tajikistan,8734951 -Tanzania,55572201 -Thailand,68863514 -Timor-Leste,1268671 -Togo,7606374 -Tonga,107122 -Trinidad and Tobago,1364962 -Tunisia,11403248 -Turkey,79512426 -Turkmenistan,5662544 -Turks and Caicos Islands,34900 -Tuvalu,11097 -Uganda,41487965 -Ukraine,45004645 -United Arab Emirates,9269612 -United Kingdom,65637239 -United States,323127513 -Uruguay,3444006 -Uzbekistan,31848200 -Vanuatu,270402 -Venezuela; RB,31568179 -Vietnam,92701100 -Virgin Islands (U.S.),102951 -West Bank and Gaza,4551566 -Yemen; Rep.,27584213 -Zambia,16591390 -Zimbabwe,16150362 diff --git a/examples/hashmap/countries/main.c b/examples/hashmap/countries/main.c deleted file mode 100644 index e93fbf0..0000000 --- a/examples/hashmap/countries/main.c +++ /dev/null @@ -1,90 +0,0 @@ -#include "cmc/hashmap.h" -#include -#include -#include -#include -#include -#include "util.c" - -HASHMAP_GENERATE(hm, hmap, , char *, size_t) - -hmap *load(const char *fname); - -int main(int argc, char const *argv[]) -{ - hmap *map = load("data.csv"); - - if (!map) - return 1; - - printf("+--------------------------------------------------+\n"); - printf("| Search Country Population by Country Name |\n"); - printf("| |\n"); - printf("| - Type 'exit' to exit |\n"); - printf("| - Type country name to search its population |\n"); - printf("+--------------------------------------------------+\n\n"); - - // If you wish to list all items - // char *key; - // size_t value, index; - - // hmap_iter iter; - // for (hm_iter_new(&iter, map); !hm_iter_end(&iter);) - // { - // hm_iter_next(&iter, &key, &value, &index); - // printf("%30s : %" PRIuMAX "\n", key, value); - - // free(key); - // } - - char sbuffer[1000]; - - while (1) - { - printf("Query > "); - fflush(stdin); - scanf("%[^\n]s", sbuffer); - - if (strcmp(sbuffer, "exit") == 0) - break; - - size_t *result = hm_get_ref(map, sbuffer); - - if (result == NULL) - printf("Result > %s Not Found\n", sbuffer); - else - printf("Result > %" PRIuMAX "\n", *result); - } - - hm_free(map); - - return 0; -} - -hmap *load(const char *fname) -{ - FILE *fptr = fopen(fname, "r"); - - if (!fptr) - return NULL; - - hmap *map = hm_new(10000, 0.7, chrcmp, chrhash); - - char buff[400]; - size_t value; - - while (fscanf(fptr, "%[^,],%" PRIuMAX "\n", buff, &value) != EOF) - { - char *name = strdup(buff); - - if (!hm_insert(map, name, value)) - { - printf("\n\n\nERROR\n"); - printf("%s : %" PRIuMAX "", name, value); - - exit(2); - } - } - - return map; -} \ No newline at end of file diff --git a/examples/hashmap/countries/util.c b/examples/hashmap/countries/util.c deleted file mode 100644 index e20c824..0000000 --- a/examples/hashmap/countries/util.c +++ /dev/null @@ -1,17 +0,0 @@ -#include - -int chrcmp(char *a, char *b) -{ - return strcmp(a, b); -} - -size_t chrhash(char *str) -{ - size_t hash = 5381; - int c; - - while ((c = *str++)) - hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ - - return hash; -} diff --git a/examples/hashmap/foreach.c b/examples/hashmap/foreach.c deleted file mode 100644 index 5835306..0000000 --- a/examples/hashmap/foreach.c +++ /dev/null @@ -1,67 +0,0 @@ -/** - * iterator.c - * - * Creation Date: 23/05/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - * Foreach macro example - */ -#include "cmc/hashmap.h" -#include "utl/foreach.h" -#include - -// Int hash function -size_t inthash(int t) -{ - size_t a = t; - a += ~(a << 15); - a ^= (a >> 10); - a += (a << 3); - a ^= (a >> 6); - a += ~(a << 11); - a ^= (a >> 16); - return a; -} - -// Int compare function -int intcmp(int a, int b) -{ - return (a > b) - (a < b); -} - -// Generate all the code for the hashmap -CMC_GENERATE_HASHMAP(hm, hashmap, int, double) -typedef struct hashmap hashmap; -typedef struct hashmap_iter hashmap_iter; - -int main(void) -{ - // Create a new hashmap with custom hash function - // The comparison function is only required to know if the key looked for was found - hashmap *map = hm_new(1000, 0.6, intcmp, inthash); - - // Add keys mapped to a value - for (int i = 0; i < 5000; i++) - { - hm_insert(map, i, (double)i / 1000.0); - } - - // Iterate over the HashMap without the FOR_EACH macro - for (hashmap_iter iter = map->it_start(map); !hm_iter_end(&iter); hm_iter_next(&iter)) - { - printf("MAP[%4d] = %.3lf\n", hm_iter_key(&iter), hm_iter_value(&iter)); - } - - // Iterate over the HashMap using FOR_EACH macro - CMC_FOR_EACH(hm, hashmap, map, { - // Inside, the variable 'iter' will be available and from it you can access - // the key, value or index. - printf("MAP[%4d] = %.3lf\n", hm_iter_key(&iter), hm_iter_value(&iter)); - }); - - hm_free(map, NULL); - - return 0; -} diff --git a/examples/hashmap/iterator.c b/examples/hashmap/iterator.c deleted file mode 100644 index d3a6260..0000000 --- a/examples/hashmap/iterator.c +++ /dev/null @@ -1,233 +0,0 @@ -/** - * iterator.c - * - * Creation Date: 14/05/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - * Iterator Example - */ -#include "cmc/hashmap.h" -#include -#include - -// Int hash function -size_t inthash(int t) -{ - size_t a = t; - a += ~(a << 15); - a ^= (a >> 10); - a += (a << 3); - a ^= (a >> 6); - a += ~(a << 11); - a ^= (a >> 16); - return a; -} - -// Int compare function -int intcmp(int a, int b) -{ - return a - b; -} - -// Creates a hashmap of integers -CMC_GENERATE_HASHMAP(hm, hashmap, int, double); -typedef struct hashmap hashmap; -typedef struct hashmap_iter hashmap_iter; - - -int main(int argc, char const *argv[]) -{ - // Create a new hashmap with an initial capacity of 100 and load factor of 0.6 - hashmap *my_map = hm_new(100, 0.6, intcmp, inthash); - - // Add pairs to the hashmap - for (int i = 0; i < 20; i++) - { - // Map integers to doubles - hm_insert(my_map, i, (double)i / 10.0); - } - - // Iterate from the start (index 0) to the end (index count - 1) of the hashmap - for (hashmap_iter it = my_map->it_start(my_map); // Initialize iterator 'it' to the start of the hashmap - !hm_iter_end(&it); // Conditional stop (until it is not at the end) - hm_iter_next(&it)) // Iterator goes one position forward - { - // Access the current key - int k = hm_iter_key(&it); - - // Access the current value - double v = hm_iter_value(&it); - - // Access the current index (index is relative to all the pairs in the iteration) - size_t i = hm_iter_index(&it); - - // Print hashmap - - // Index is useful in situations like this - // If it is the first pair - if (i == 0) - printf("[ {%d:%.2lf}, ", k, v); - // If it is the last pair - else if (i == hm_count(my_map) - 1) - printf("{%d:%.2lf} ]\n", k, v); - // For pairs at the middle - else - printf("{%d:%.2lf}, ", k, v); - } - - // Index can also be used to iterate over a certain portion of a collection - size_t limit = hm_count(my_map) / 2; - for (hashmap_iter it = my_map->it_start(my_map); !hm_iter_end(&it); hm_iter_next(&it)) - { - // Access the current key - int k = hm_iter_key(&it); - - // Access the current value - double v = hm_iter_value(&it); - - // Access the current index (index is relative to all the pairs in the iteration) - size_t i = hm_iter_index(&it); - - // Print hashmap up until limit - - // If it is the first pair - if (i == 0) - printf("[ {%d:%.2lf}, ", k, v); - // If it is the last pair - else if (i == limit - 1) // -1 because index is 0 based and we want half of the hashmap - { - printf("{%d:%.2lf} ]\n", k, v); - break; - } - // For pairs at the middle - else - printf("{%d:%.2lf}, ", k, v); - } - - // Going backwards - for (hashmap_iter it = my_map->it_end(my_map); // Initialize iterator 'it' to the end of the hashmap - !hm_iter_start(&it); // Conditional stop (until it is not at the start) - hm_iter_prev(&it)) // Iterator goes one position backwards - { - // Access the current key - int k = hm_iter_key(&it); - - // Access the current value - double v = hm_iter_value(&it); - - // Access the current index (index is relative to all the pairs in the iteration) - size_t i = hm_iter_index(&it); - - // Print hashmap - // Note how the conditions for the first and last pairs are simply swapped - // Because iterating backwards make the first pair be the index count - 1 - // and the last one be the index 0 - - // If it is the first pair - if (i == hm_count(my_map) - 1) - printf("[ {%d:%.2lf}, ", k, v); - // If it is the last pair - else if (i == 0) - printf("{%d:%.2lf} ]\n", k, v); - // For pairs at the middle - else - printf("{%d:%.2lf}, ", k, v); - } - - // You can also use iterators in a while loop - // But to do so you must declare the iterator struct outside the loop first - hashmap_iter it; - - // You have three options: - // - Initialize it using the functions provided by the hashmap [ my_map->it_start() and my_map->it_end() ] - // - Initialize it using the init() function (when the iterator is already allocated) - // - Initialize it using the new() function (allocates on the heap, pointers only) - - it = my_map->it_start(my_map); - it = my_map->it_end(my_map); - - // This is equivalent to it_start() - hm_iter_init(&it, my_map); - - // For pointers - // Also equivalent to it_start() - hashmap_iter *iter = hm_iter_new(my_map); - - // The actual while loop - while (!hm_iter_end(iter)) - { - // Accessing pairs - int k = hm_iter_key(iter); - double v = hm_iter_value(iter); - size_t i = hm_iter_index(iter); - - // Print index and key value pair - printf("hashmap[%2" PRIuMAX "] = { %2d : %.2lf }\n", i, k, v); - - // Move iterator forwards - hm_iter_next(iter); - } - - // Send the iterator to the start of the hashmap - hm_iter_to_start(iter); - - // Send the iterator to the end of the hashmap - hm_iter_to_end(iter); - - // Backwards loop - while (!hm_iter_start(iter)) - { - // Accessing pairs - int k = hm_iter_key(iter); - double v = hm_iter_value(iter); - size_t i = hm_iter_index(iter); - - // Print index and the key value pair - printf("hashmap[%2" PRIuMAX "] = { %2d : %.2lf }\n", i, k, v); - - // Move iterator backwards - hm_iter_prev(iter); - } - - // Certain iterators also allow you to modify the contents it is iterating over - // Exceptions are collections that depend of the current state of the pair - // like tree-based collections and heap (collections that have some kind of ordering). - // You also can't change the keys of an associative collection - - // Change every value where its key is divisible by 3 to the number 7 - for (hm_iter_to_start(&it); !hm_iter_end(&it); hm_iter_next(&it)) - { - // Get current key - int k = hm_iter_key(&it); - - // Get a reference to the current value - double *v = hm_iter_rvalue(&it); - - if (k % 3 == 0) - *v = 7; - } - - // Now print it to see the difference - for (hashmap_iter it = my_map->it_start(my_map); !hm_iter_end(&it); hm_iter_next(&it)) - { - int k = hm_iter_key(&it); - double v = hm_iter_value(&it); - size_t i = hm_iter_index(&it); - - if (i == 0) - printf("[ {%d:%.2lf}, ", k, v); - else if (i == hm_count(my_map) - 1) - printf("{%d:%.2lf} ]\n", k, v); - else - printf("{%d:%.2lf}, ", k, v); - } - - // Dispose the iterator called by hm_iter_new() - hm_iter_free(iter); - // Dispose the hashmap created - hm_free(my_map, NULL); - - return 0; -} diff --git a/examples/hashset/README.md b/examples/hashset/README.md deleted file mode 100644 index 1d544e7..0000000 --- a/examples/hashset/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Hashset examples - -* iterator.c - A complete example of the hashset iterator -* set_ops.c - Demonstrates common set operations like *union*, *intersection*, *difference* and *symmetric difference*. diff --git a/examples/hashset/iterator.c b/examples/hashset/iterator.c deleted file mode 100644 index ec99501..0000000 --- a/examples/hashset/iterator.c +++ /dev/null @@ -1,196 +0,0 @@ -/** - * iterator.c - * - * Creation Date: 15/05/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - * Iterator Example - */ -#include "cmc/hashset.h" -#include -#include - -// Int hash function -size_t inthash(int t) -{ - size_t a = t; - a += ~(a << 15); - a ^= (a >> 10); - a += (a << 3); - a ^= (a >> 6); - a += ~(a << 11); - a ^= (a >> 16); - return a; -} - -// Int compare function -int intcmp(int a, int b) -{ - return a - b; -} - -// Creates a hashset of integers -CMC_GENERATE_HASHSET(hs, hashset, int) -typedef struct hashset hashset; -typedef struct hashset_iter hashset_iter; - -int main(int argc, char const *argv[]) -{ - // Create a new hashset with an initial capacity of 100 and load factor of 0.6 - hashset *my_hashset = hs_new(100, 0.6, intcmp, inthash); - - // Add elements to the hashset - for (int i = 0; i < 20; i++) - { - hs_insert(my_hashset, i); - } - - // Iterate from the start (index 0) to the end (index count - 1) of the hashset - for (hashset_iter it = my_hashset->it_start(my_hashset); // Initialize iterator 'it' to the start of the hashset - !hs_iter_end(&it); // Conditional stop (until it is not at the end) - hs_iter_next(&it)) // Iterator goes one position forward - { - // Access the current element - int e = hs_iter_value(&it); - - // Access the current index (index is relative to all the elements in the iteration) - size_t i = hs_iter_index(&it); - - // Print hashset - - // Index is useful in situations like this - // If it is the first element - if (i == 0) - printf("[ %d, ", e); - // If it is the last element - else if (i == hs_count(my_hashset) - 1) - printf("%d ]\n", e); - // For elements at the middle - else - printf("%d, ", e); - } - - // Index can also be used to iterate over a certain portion of a collection - size_t limit = hs_count(my_hashset) / 2; - for (hashset_iter it = my_hashset->it_start(my_hashset); !hs_iter_end(&it); hs_iter_next(&it)) - { - // Access the current element - int e = hs_iter_value(&it); - - // Access the current index (index is relative to all the elements in the iteration) - size_t i = hs_iter_index(&it); - - // Print hashset up until limit - - // If it is the first element - if (i == 0) - printf("[ %d, ", e); - // If it is the last element - else if (i == limit - 1) // -1 because index is 0 based and we want half of the hashset - { - printf("%d ]\n", e); - break; - } - // For elements at the middle - else - printf("%d, ", e); - } - - // Going backwards - for (hashset_iter it = my_hashset->it_end(my_hashset); // Initialize iterator 'it' to the end of the hashset - !hs_iter_start(&it); // Conditional stop (until it is not at the start) - hs_iter_prev(&it)) // Iterator goes one position backwards - { - // Access the current element - int e = hs_iter_value(&it); - - // Access the current index (index is relative to all the elements in the iteration) - size_t i = hs_iter_index(&it); - - // Print hashset - // Note how the conditions for the first and last elements are simply swapped - // Because iterating backwards make the first element be the index count - 1 - // and the last one be the index 0 - - // If it is the first element - if (i == hs_count(my_hashset) - 1) - printf("[ %d, ", e); - // If it is the last element - else if (i == 0) - printf("%d ]\n", e); - // For elements at the middle - else - printf("%d, ", e); - } - - // You can also use iterators in a while loop - // But to do so you must declare the iterator struct outside the loop first - hashset_iter it; - - // You have three options: - // - Initialize it using the functions provided by the hashset [ my_hashset->it_start() and my_hashset->it_end() ] - // - Initialize it using the init() function (when the iterator is already allocated) - // - Initialize it using the new() function (allocates on the heap, pointers only) - - it = my_hashset->it_start(my_hashset); - it = my_hashset->it_end(my_hashset); - - // This is equivalent to it_start() - hs_iter_init(&it, my_hashset); - - // For pointers - // Also equivalent to it_start() - hashset_iter *iter = hs_iter_new(my_hashset); - - // The actual while loop - while (!hs_iter_end(iter)) - { - // Accessing elements - int e = hs_iter_value(iter); - size_t i = hs_iter_index(iter); - - // Print index and element - printf("hashset[%2" PRIuMAX "] = %2d\n", i, e); - - // Move iterator forwards - hs_iter_next(iter); - } - - // Send the iterator to the start of the hashset - hs_iter_to_start(iter); - - // Send the iterator to the end of the hashset - hs_iter_to_end(iter); - - // Backwards loop - while (!hs_iter_start(iter)) - { - // Accessing elements - int e = hs_iter_value(iter); - size_t i = hs_iter_index(iter); - - // Print index and element - printf("hashset[%2" PRIuMAX "] = %2d\n", i, e); - - // Move iterator backwards - hs_iter_prev(iter); - } - - // Certain iterators also allow you to modify the contents it is iterating over - // Exceptions are collections that depend of the current state of the element - // like tree-based collections and heap (collections that have some kind of ordering). - // You also can't change the keys of an associative collection - - // In the case of a hashset or any set, this is not possible because the - // values of a set are its keys. Changing the elements could cause the set - // to be in an invalid state. - - // Dispose the iterator called by hs_iter_new() - hs_iter_free(iter); - // Dispose the hashset created - hs_free(my_hashset, NULL); - - return 0; -} diff --git a/examples/hashset/set_ops.c b/examples/hashset/set_ops.c deleted file mode 100644 index 7e1e1a1..0000000 --- a/examples/hashset/set_ops.c +++ /dev/null @@ -1,118 +0,0 @@ -/** - * set_ops.c - * - * Creation Date: 03/04/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -// Demonstration of set operations like: -// - Union -// - Intersection -// - Difference -// - Symmetric Difference - -#include "cmc/hashset.h" -#include -#include - -CMC_GENERATE_HASHSET(set, set, int) -typedef struct set set; -typedef struct set_iter set_iter; - - -void print_set(set *s) -{ - set_iter iter; - set_iter_init(&iter, s); - for (set_iter_to_start(&iter); !set_iter_end(&iter); set_iter_next(&iter)) - { - int result = set_iter_value(&iter); - size_t index = set_iter_index(&iter); - - if (index == 0) - printf("[ %2d, ", result); - else if (index == s->count - 1) - printf("%2d ]\n", result); - else - printf("%2d, ", result); - } -} - -int intcmp(int a, int b) -{ - return a - b; -} - -size_t inthash(int t) -{ - size_t a = t; - a += ~(a << 15); - a ^= (a >> 10); - a += (a << 3); - a ^= (a >> 6); - a += ~(a << 11); - a ^= (a >> 16); - return a; -} - -int main(int argc, char const *argv[]) -{ - set *set1 = set_new(50, 0.9, intcmp, inthash); - set *set2 = set_new(50, 0.9, intcmp, inthash); - - for (int i = 1; i <= 20; i++) - set_insert(set1, i); - - for (int i = 11; i <= 30; i++) - set_insert(set2, i); - - set *set3 = set_union(set1, set2); - - print_set(set1); - printf("UNION\n"); - print_set(set2); - printf("=\n"); - print_set(set3); - - printf("\n\n"); - - set *set4 = set_intersection(set1, set2); - - print_set(set1); - printf("INTERSECTION\n"); - print_set(set2); - printf("=\n"); - print_set(set4); - - printf("\n\n"); - - set *set5 = set_difference(set1, set2); - - print_set(set1); - printf("DIFFERENCE\n"); - print_set(set2); - printf("=\n"); - print_set(set5); - - printf("\n\n"); - - set *set6 = set_symmetric_difference(set1, set2); - - print_set(set1); - printf("SYMMETRIC DIFFERENCE\n"); - print_set(set2); - printf("=\n"); - print_set(set6); - - set_free(set1, NULL); - set_free(set2, NULL); - set_free(set3, NULL); - set_free(set4, NULL); - set_free(set5, NULL); - set_free(set6, NULL); - - return 0; -} diff --git a/examples/heap/README.md b/examples/heap/README.md deleted file mode 100644 index 5b402b4..0000000 --- a/examples/heap/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Heap examples - -* heapsort.c - Uses the heap to sort the elements in a given array. -* iterator.c - A complete example of the heap iterator diff --git a/examples/heap/heapsort.c b/examples/heap/heapsort.c deleted file mode 100644 index 4064e1a..0000000 --- a/examples/heap/heapsort.c +++ /dev/null @@ -1,58 +0,0 @@ -/** - * heapsort.c - * - * Creation Date: 25/03/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ -#include "cmc/heap.h" -#include - -static int intcmp(int a, int b) -{ - return a - b; -} - -CMC_GENERATE_HEAP(h, heap, int) -typedef struct heap heap; -typedef struct heap_iter heap_iter; - - -int main(int argc, char const *argv[]) -{ - heap *h = h_new(32, cmc_max_heap, intcmp); - - for (int i = 1; i < 101; i++) - { - h_insert(h, i); - } - - size_t S = h_count(h); - - int *buff = malloc(sizeof(int) * S); - - int index = 0; - while (!h_empty(h)) - { - int tmp; - h_remove(h, &tmp); - buff[index++] = tmp; - } - - for (size_t i = 0; i < S; i++) - { - if (i == 0) - printf("[ %d, ", buff[i]); - else if (i == S - 1) - printf("%d ]\n", buff[i]); - else - printf("%d, ", buff[i]); - } - - free(buff); - h_free(h, NULL); - - return 0; -} diff --git a/examples/heap/iterator.c b/examples/heap/iterator.c deleted file mode 100644 index 7d85c74..0000000 --- a/examples/heap/iterator.c +++ /dev/null @@ -1,184 +0,0 @@ -/** - * iterator.c - * - * Creation Date: 15/05/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - * Iterator Example - */ -#include "cmc/heap.h" -#include -#include - -// Int compare function -int intcmp(int a, int b) -{ - return a - b; -} - -// Creates a heap of integers -CMC_GENERATE_HEAP(h, heap, int); -typedef struct heap heap; -typedef struct heap_iter heap_iter; - - -int main(int argc, char const *argv[]) -{ - // Create a new max heap with an initial capacity of 100 - heap *my_heap = h_new(100, cmc_max_heap, intcmp); - - // Add elements to the heap - for (int i = 0; i < 20; i++) - { - h_insert(my_heap, i); - } - - // Iterate from the start (index 0) to the end (index count - 1) of the heap - for (heap_iter it = my_heap->it_start(my_heap); // Initialize iterator 'it' to the start of the heap - !h_iter_end(&it); // Conditional stop (until it is not at the end) - h_iter_next(&it)) // Iterator goes one position forward - { - // Access the current element - int e = h_iter_value(&it); - - // Access the current index (index is relative to all the elements in the iteration) - size_t i = h_iter_index(&it); - - // Print heap - - // Index is useful in situations like this - // If it is the first element - if (i == 0) - printf("[ %d, ", e); - // If it is the last element - else if (i == h_count(my_heap) - 1) - printf("%d ]\n", e); - // For elements at the middle - else - printf("%d, ", e); - } - - // Index can also be used to iterate over a certain portion of a collection - size_t limit = h_count(my_heap) / 2; - for (heap_iter it = my_heap->it_start(my_heap); !h_iter_end(&it); h_iter_next(&it)) - { - // Access the current element - int e = h_iter_value(&it); - - // Access the current index (index is relative to all the elements in the iteration) - size_t i = h_iter_index(&it); - - // Print heap up until limit - - // If it is the first element - if (i == 0) - printf("[ %d, ", e); - // If it is the last element - else if (i == limit - 1) // -1 because index is 0 based and we want half of the heap - { - printf("%d ]\n", e); - break; - } - // For elements at the middle - else - printf("%d, ", e); - } - - // Going backwards - for (heap_iter it = my_heap->it_end(my_heap); // Initialize iterator 'it' to the end of the heap - !h_iter_start(&it); // Conditional stop (until it is not at the start) - h_iter_prev(&it)) // Iterator goes one position backwards - { - // Access the current element - int e = h_iter_value(&it); - - // Access the current index (index is relative to all the elements in the iteration) - size_t i = h_iter_index(&it); - - // Print heap - // Note how the conditions for the first and last elements are simply swapped - // Because iterating backwards make the first element be the index count - 1 - // and the last one be the index 0 - - // If it is the first element - if (i == h_count(my_heap) - 1) - printf("[ %d, ", e); - // If it is the last element - else if (i == 0) - printf("%d ]\n", e); - // For elements at the middle - else - printf("%d, ", e); - } - - // You can also use iterators in a while loop - // But to do so you must declare the iterator struct outside the loop first - heap_iter it; - - // You have three options: - // - Initialize it using the functions provided by the heap [ my_heap->it_start() and my_heap->it_end() ] - // - Initialize it using the init() function (when the iterator is already allocated) - // - Initialize it using the new() function (allocates on the heap, pointers only) - - it = my_heap->it_start(my_heap); - it = my_heap->it_end(my_heap); - - // This is equivalent to it_start() - h_iter_init(&it, my_heap); - - // For pointers - // Also equivalent to it_start() - heap_iter *iter = h_iter_new(my_heap); - - // The actual while loop - while (!h_iter_end(iter)) - { - // Accessing elements - int e = h_iter_value(iter); - size_t i = h_iter_index(iter); - - // Print index and element - printf("heap[%2" PRIuMAX "] = %2d\n", i, e); - - // Move iterator forwards - h_iter_next(iter); - } - - // Send the iterator to the start of the heap - h_iter_to_start(iter); - - // Send the iterator to the end of the heap - h_iter_to_end(iter); - - // Backwards loop - while (!h_iter_start(iter)) - { - // Accessing elements - int e = h_iter_value(iter); - size_t i = h_iter_index(iter); - - // Print index and element - printf("heap[%2" PRIuMAX "] = %2d\n", i, e); - - // Move iterator backwards - h_iter_prev(iter); - } - - // Certain iterators also allow you to modify the contents it is iterating over - // Exceptions are collections that depend of the current state of the element - // like tree-based collections and heap (collections that have some kind of ordering). - // You also can't change the keys of an associative collection - - // In the case of a heap this is not possible because the heap have its - // elements ordered. Changing them could cause the heap to be in an invalid - // state. - - // Dispose the iterator called by h_iter_new() - h_iter_free(iter); - // Dispose the heap created - h_free(my_heap, NULL); - - return 0; -} diff --git a/examples/iterators/deque.c b/examples/iterators/deque.c deleted file mode 100644 index ecd6952..0000000 --- a/examples/iterators/deque.c +++ /dev/null @@ -1,62 +0,0 @@ -/** - * deque.c - * - * Creation Date: 11/04/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ -#include "cmc/deque.h" -#include - -CMC_GENERATE_DEQUE(d, deque, int); -typedef struct deque deque; -typedef struct deque_iter deque_iter; - -int main(int argc, char const *argv[]) -{ - // Initialize deque and add some elements - deque *d = d_new(10); - for (int i = 0; i < 10; i++) - { - i % 2 == 0 ? d_push_back(d, i) : d_push_front(d, i); - } - - // Initialize iterator - deque_iter iter; - d_iter_init(&iter, d); - - // Make the iterator go back and forward - for (int j = 0; j < 4; j++) - { - while (!d_iter_end(&iter)) - { - printf("C[%2d] = %2d\n", d_iter_index(&iter), d_iter_value(&iter)); - d_iter_next(&iter); - } - printf("\n"); - while (!d_iter_start(&iter)) - { - printf("C[%2d] = %2d\n", d_iter_index(&iter), d_iter_value(&iter)); - d_iter_prev(&iter); - } - printf("\n\n"); - } - - for (d_iter_to_start(&iter); !d_iter_end(&iter); d_iter_next(&iter)) - { - printf("D[%2d] = %2d\n", d_iter_index(&iter), d_iter_value(&iter)); - } - - printf("\n"); - - for (d_iter_to_end(&iter); !d_iter_start(&iter); d_iter_prev(&iter)) - { - printf("D[%2d] = %2d\n", d_iter_index(&iter), d_iter_value(&iter)); - } - - d_free(d, NULL); - - return 0; -} diff --git a/examples/iterators/hashmap.c b/examples/iterators/hashmap.c deleted file mode 100644 index 3167a84..0000000 --- a/examples/iterators/hashmap.c +++ /dev/null @@ -1,79 +0,0 @@ -/** - * hashmap.c - * - * Creation Date: 11/04/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ -#include "cmc/hashmap.h" -#include - -CMC_GENERATE_HASHMAP(hm, hmap, int, double) -typedef struct hmap hmap; -typedef struct hmap_iter hmap_iter; - - -size_t inthash(int t) -{ - size_t a = t; - a += ~(a << 15); - a ^= (a >> 10); - a += (a << 3); - a ^= (a >> 6); - a += ~(a << 11); - a ^= (a >> 16); - return a; -} - -int intcmp(int a, int b) -{ - return (a > b) - (a < b); -} - -int main(int argc, char const *argv[]) -{ - double varr[10] = {0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9}; - - // Initialize hashmap and add some element - hmap *hm = hm_new(50, 0.9, intcmp, inthash); - for (int i = 0; i < 10; i++) - hm_insert(hm, i, varr[i]); - - // Initialize iterator - hmap_iter iter; - hm_iter_init(&iter, hm); - - for (int j = 0; j < 4; j++) - { - while (!hm_iter_end(&iter)) - { - printf("C[%2d] = { %2d : %2.2lf }\n", hm_iter_index(&iter), hm_iter_key(&iter), hm_iter_value(&iter)); - hm_iter_next(&iter); - } - printf("\n"); - while (!hm_iter_start(&iter)) - { - printf("C[%2d] = { %2d : %2.2lf }\n", hm_iter_index(&iter), hm_iter_key(&iter), hm_iter_value(&iter)); - hm_iter_prev(&iter); - } - printf("\n\n"); - } - - for (hm_iter_to_start(&iter); !hm_iter_end(&iter); hm_iter_next(&iter)) - { - printf("HM[%2d] = { %2d : %2.2lf }\n", hm_iter_index(&iter), hm_iter_key(&iter), hm_iter_value(&iter)); - } - - printf("\n"); - - for (hm_iter_to_end(&iter); !hm_iter_start(&iter); hm_iter_prev(&iter)) - { - printf("HM[%2d] = { %2d : %2.2lf }\n", hm_iter_index(&iter), hm_iter_key(&iter), hm_iter_value(&iter)); - } - - hm_free(hm, NULL); - - return 0; -} diff --git a/examples/iterators/hashset.c b/examples/iterators/hashset.c deleted file mode 100644 index 3552017..0000000 --- a/examples/iterators/hashset.c +++ /dev/null @@ -1,78 +0,0 @@ -/** - * hashset.c - * - * Creation Date: 11/04/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ -#include "cmc/hashset.h" -#include - -CMC_GENERATE_HASHSET(hs, hset, int); -typedef struct hset hset; -typedef struct hset_iter hset_iter; - - -size_t inthash(int t) -{ - size_t a = t; - a += ~(a << 15); - a ^= (a >> 10); - a += (a << 3); - a ^= (a >> 6); - a += ~(a << 11); - a ^= (a >> 16); - return a; -} - -int intcmp(int a, int b) -{ - return (a > b) - (a < b); -} - -int main(int argc, char const *argv[]) -{ - // Initialize hashset and add some elements - hset *hs = hs_new(10, 0.9, intcmp, inthash); - for (int i = 0; i < 10; i++) - hs_insert(hs, i); - - // Initialize iterator - hset_iter iter; - hs_iter_init(&iter, hs); - - // Make the iterator go back and forward - for (int j = 0; j < 4; j++) - { - while (!hs_iter_end(&iter)) - { - printf("C[%2d] = %2d\n", hs_iter_index(&iter), hs_iter_value(&iter)); - hs_iter_next(&iter); - } - printf("\n"); - while (!hs_iter_start(&iter)) - { - printf("C[%2d] = %2d\n", hs_iter_index(&iter), hs_iter_value(&iter)); - hs_iter_prev(&iter); - } - printf("\n\n"); - } - - for (hs_iter_to_start(&iter); !hs_iter_end(&iter); hs_iter_next(&iter)) - { - printf("HS[%2d] = %2d\n", hs_iter_index(&iter), hs_iter_value(&iter)); - } - - printf("\n"); - - for (hs_iter_to_end(&iter); !hs_iter_start(&iter); hs_iter_prev(&iter)) - { - printf("HS[%2d] = %2d\n", hs_iter_index(&iter), hs_iter_value(&iter)); - } - - hs_free(hs, NULL); - - return 0; -} diff --git a/examples/iterators/heap.c b/examples/iterators/heap.c deleted file mode 100644 index 7eac514..0000000 --- a/examples/iterators/heap.c +++ /dev/null @@ -1,67 +0,0 @@ -/** - * heap.c - * - * Creation Date: 11/04/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ -#include "cmc/heap.h" -#include - -int intcmp(int a, int b) -{ - return (a > b) - (a < b); -} - - -CMC_GENERATE_HEAP(h, heap, int) -typedef struct heap heap; -typedef struct heap_iter heap_iter; - - -int main(int argc, char const *argv[]) -{ - // Initialize heap and add some elements - heap *h = h_new(10, cmc_max_heap, intcmp); - for (int i = 0; i < 10; i++) - h_insert(h, i); - - // Initialize iterator - heap_iter iter; - h_iter_init(&iter, h); - - // Make the iterator go back and forward - for (int j = 0; j < 4; j++) - { - while (!h_iter_end(&iter)) - { - printf("C[%2d] = %2d\n", h_iter_index(&iter), h_iter_value(&iter)); - h_iter_next(&iter); - } - printf("\n"); - while (!h_iter_start(&iter)) - { - printf("C[%2d] = %2d\n", h_iter_index(&iter), h_iter_value(&iter)); - h_iter_prev(&iter); - } - printf("\n\n"); - } - - for (h_iter_to_start(&iter); !h_iter_end(&iter); h_iter_next(&iter)) - { - printf("H[%2d] = %2d\n", h_iter_index(&iter), h_iter_value(&iter)); - } - - printf("\n"); - - for (h_iter_to_end(&iter); !h_iter_start(&iter); h_iter_prev(&iter)) - { - printf("H[%2d] = %2d\n", h_iter_index(&iter), h_iter_value(&iter)); - } - - h_free(h, NULL); - - return 0; -} diff --git a/examples/iterators/linkedlist.c b/examples/iterators/linkedlist.c deleted file mode 100644 index de5ceba..0000000 --- a/examples/iterators/linkedlist.c +++ /dev/null @@ -1,61 +0,0 @@ -/** - * linkedlist.c - * - * Creation Date: 11/04/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ -#include "cmc/linkedlist.h" -#include - -CMC_GENERATE_LINKEDLIST(ll, linkedlist, int); -typedef struct linkedlist linkedlist; -typedef struct linkedlist_iter linkedlist_iter; - - -int main(int argc, char const *argv[]) -{ - // Initialize linkedlist and add some elements - linkedlist *ll = ll_new(); - for (int i = 0; i < 10; i++) - ll_push_back(ll, i); - - // Initialize iterator - linkedlist_iter iter; - ll_iter_init(&iter, ll); - - // Make the iterator go back and forward - for (int j = 0; j < 4; j++) - { - while (!ll_iter_end(&iter)) - { - printf("C[%2d] = %2d\n", ll_iter_index(&iter), ll_iter_value(&iter)); - ll_iter_next(&iter); - } - printf("\n"); - while (!ll_iter_start(&iter)) - { - printf("C[%2d] = %2d\n", ll_iter_index(&iter), ll_iter_value(&iter)); - ll_iter_prev(&iter); - } - printf("\n\n"); - } - - for (ll_iter_to_start(&iter); !ll_iter_end(&iter); ll_iter_next(&iter)) - { - printf("LL[%2d] = %2d\n", ll_iter_index(&iter), ll_iter_value(&iter)); - } - - printf("\n"); - - for (ll_iter_to_end(&iter); !ll_iter_start(&iter); ll_iter_prev(&iter)) - { - printf("LL[%2d] = %2d\n", ll_iter_index(&iter), ll_iter_value(&iter)); - } - - ll_free(ll, NULL); - - return 0; -} diff --git a/examples/iterators/list.c b/examples/iterators/list.c deleted file mode 100644 index 622d871..0000000 --- a/examples/iterators/list.c +++ /dev/null @@ -1,61 +0,0 @@ -/** - * list.c - * - * Creation Date: 11/04/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ -#include "cmc/list.h" -#include - -CMC_GENERATE_LIST(l, list, int); -typedef struct list list; -typedef struct list_iter list_iter; - - -int main(int argc, char const *argv[]) -{ - // Initialize list and add some elements - list *l = l_new(10); - for (int i = 0; i < 10; i++) - l_push_back(l, i); - - // Initialize iterator - list_iter iter; - l_iter_init(&iter, l); - - // Make the iterator go back and forward - for (int j = 0; j < 4; j++) - { - while (!l_iter_end(&iter)) - { - printf("C[%2d] = %2d\n", l_iter_index(&iter), l_iter_value(&iter)); - l_iter_next(&iter); - } - printf("\n"); - while (!l_iter_start(&iter)) - { - printf("C[%2d] = %2d\n", l_iter_index(&iter), l_iter_value(&iter)); - l_iter_prev(&iter); - } - printf("\n\n"); - } - - for (l_iter_to_start(&iter); !l_iter_end(&iter); l_iter_next(&iter)) - { - printf("L[%2d] = %2d\n", l_iter_index(&iter), l_iter_value(&iter)); - } - - printf("\n"); - - for (l_iter_to_end(&iter); !l_iter_start(&iter); l_iter_prev(&iter)) - { - printf("L[%2d] = %2d\n", l_iter_index(&iter), l_iter_value(&iter)); - } - - l_free(l, NULL); - - return 0; -} diff --git a/examples/iterators/queue.c b/examples/iterators/queue.c deleted file mode 100644 index 7457c43..0000000 --- a/examples/iterators/queue.c +++ /dev/null @@ -1,61 +0,0 @@ -/** - * queue.c - * - * Creation Date: 11/04/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ -#include "cmc/queue.h" -#include - -CMC_GENERATE_QUEUE(q, queue, int) -typedef struct queue queue; -typedef struct queue_iter queue_iter; - - -int main(int argc, char const *argv[]) -{ - // Initialize queue and add some elements - queue *q = q_new(10); - for (int i = 0; i < 10; i++) - q_enqueue(q, i); - - // Initialize iterator - queue_iter iter; - q_iter_init(&iter, q); - - // Make the iterator go back and forward - for (int j = 0; j < 4; j++) - { - while (!q_iter_end(&iter)) - { - printf("C[%2d] = %2d\n", q_iter_index(&iter), q_iter_value(&iter)); - q_iter_next(&iter); - } - printf("\n"); - while (!q_iter_start(&iter)) - { - printf("C[%2d] = %2d\n", q_iter_index(&iter), q_iter_value(&iter)); - q_iter_prev(&iter); - } - printf("\n\n"); - } - - for (q_iter_to_start(&iter); !q_iter_end(&iter); q_iter_next(&iter)) - { - printf("Q[%2d] = %2d\n", q_iter_index(&iter), q_iter_value(&iter)); - } - - printf("\n"); - - for (q_iter_to_end(&iter); !q_iter_start(&iter); q_iter_prev(&iter)) - { - printf("Q[%2d] = %2d\n", q_iter_index(&iter), q_iter_value(&iter)); - } - - q_free(q, NULL); - - return 0; -} diff --git a/examples/iterators/stack.c b/examples/iterators/stack.c deleted file mode 100644 index c8f8d41..0000000 --- a/examples/iterators/stack.c +++ /dev/null @@ -1,61 +0,0 @@ -/** - * stack.c - * - * Creation Date: 11/04/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ -#include "cmc/stack.h" -#include - -CMC_GENERATE_STACK(s, stack, int) -typedef struct stack stack; -typedef struct stack_iter stack_iter; - - -int main(int argc, char const *argv[]) -{ - // Initialize stack and add some elements - stack *s = s_new(10); - for (int i = 0; i < 10; i++) - s_push(s, i); - - // Initialize iterator - stack_iter iter; - s_iter_init(&iter, s); - - // Make the iterator go back and forward - for (int j = 0; j < 4; j++) - { - while (!s_iter_end(&iter)) - { - printf("C[%2d] = %2d\n", s_iter_index(&iter), s_iter_value(&iter)); - s_iter_next(&iter); - } - printf("\n"); - while (!s_iter_start(&iter)) - { - printf("C[%2d] = %2d\n", s_iter_index(&iter), s_iter_value(&iter)); - s_iter_prev(&iter); - } - printf("\n\n"); - } - - for (s_iter_to_start(&iter); !s_iter_end(&iter); s_iter_next(&iter)) - { - printf("S[%2d] = %2d\n", s_iter_index(&iter), s_iter_value(&iter)); - } - - printf("\n"); - - for (s_iter_to_end(&iter); !s_iter_start(&iter); s_iter_prev(&iter)) - { - printf("S[%2d] = %2d\n", s_iter_index(&iter), s_iter_value(&iter)); - } - - s_free(s, NULL); - - return 0; -} diff --git a/examples/iterators/treemap.c b/examples/iterators/treemap.c deleted file mode 100644 index a8821b4..0000000 --- a/examples/iterators/treemap.c +++ /dev/null @@ -1,67 +0,0 @@ -/** - * treemap.c - * - * Creation Date: 11/04/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ -#include "cmc/treemap.h" -#include - -int intcmp(int a, int b) -{ - return (a > b) - (a < b); -} - -CMC_GENERATE_TREEMAP(tm, tmap, int, double) -typedef struct tmap tmap; -typedef struct tmap_iter tmap_iter; - - -int main(int argc, char const *argv[]) -{ - double varr[10] = {0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9}; - - // Initialize treemap and add some element - tmap *hm = tm_new(intcmp); - for (int i = 0; i < 10; i++) - tm_insert(hm, i, varr[i]); - - // Initialize iterator - tmap_iter iter; - tm_iter_init(&iter, hm); - - for (int j = 0; j < 4; j++) - { - while (!tm_iter_end(&iter)) - { - printf("C[%2d] = { %2d : %2.2lf }\n", tm_iter_index(&iter), tm_iter_key(&iter), tm_iter_value(&iter)); - tm_iter_next(&iter); - } - printf("\n"); - while (!tm_iter_start(&iter)) - { - printf("C[%2d] = { %2d : %2.2lf }\n", tm_iter_index(&iter), tm_iter_key(&iter), tm_iter_value(&iter)); - tm_iter_prev(&iter); - } - printf("\n\n"); - } - - for (tm_iter_to_start(&iter); !tm_iter_end(&iter); tm_iter_next(&iter)) - { - printf("TM[%2d] = { %2d : %2.2lf }\n", tm_iter_index(&iter), tm_iter_key(&iter), tm_iter_value(&iter)); - } - - printf("\n"); - - for (tm_iter_to_end(&iter); !tm_iter_start(&iter); tm_iter_prev(&iter)) - { - printf("TM[%2d] = { %2d : %2.2lf }\n", tm_iter_index(&iter), tm_iter_key(&iter), tm_iter_value(&iter)); - } - - tm_free(hm, NULL); - - return 0; -} diff --git a/examples/iterators/treeset.c b/examples/iterators/treeset.c deleted file mode 100644 index 42dbc61..0000000 --- a/examples/iterators/treeset.c +++ /dev/null @@ -1,66 +0,0 @@ -/** - * treeset.c - * - * Creation Date: 11/04/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ -#include "cmc/treeset.h" -#include - -int intcmp(int a, int b) -{ - return (a > b) - (a < b); -} - -CMC_GENERATE_TREESET(ts, tset, int); -typedef struct tset tset; -typedef struct tset_iter tset_iter; - - -int main(int argc, char const *argv[]) -{ - // Initialize treeset and add some elements - tset *ts = ts_new(intcmp); - for (int i = 0; i < 10; i++) - ts_insert(ts, i); - - // Initialize iterator - tset_iter iter; - ts_iter_init(&iter, ts); - - // Make the iterator go back and forward - for (int j = 0; j < 4; j++) - { - while (!ts_iter_end(&iter)) - { - printf("C[%2d] = %2d\n", ts_iter_index(&iter), ts_iter_value(&iter)); - ts_iter_next(&iter); - } - printf("\n"); - while (!ts_iter_start(&iter)) - { - printf("C[%2d] = %2d\n", ts_iter_index(&iter), ts_iter_value(&iter)); - ts_iter_prev(&iter); - } - printf("\n\n"); - } - - for (ts_iter_to_start(&iter); !ts_iter_end(&iter); ts_iter_next(&iter)) - { - printf("TS[%2d] = %2d\n", ts_iter_index(&iter), ts_iter_value(&iter)); - } - - printf("\n"); - - for (ts_iter_to_end(&iter); !ts_iter_start(&iter); ts_iter_prev(&iter)) - { - printf("TS[%2d] = %2d\n", ts_iter_index(&iter), ts_iter_value(&iter)); - } - - ts_free(ts, NULL); - - return 0; -} diff --git a/examples/linkedlist/README.md b/examples/linkedlist/README.md deleted file mode 100644 index 816a805..0000000 --- a/examples/linkedlist/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Linkedlist examples - -* iterator.c - A complete example of the linked list iterator -* linked_list_node.c - Example of using functions that add or remove elements relative to a node. diff --git a/examples/linkedlist/iterator.c b/examples/linkedlist/iterator.c deleted file mode 100644 index c7c40d0..0000000 --- a/examples/linkedlist/iterator.c +++ /dev/null @@ -1,195 +0,0 @@ -/** - * iterator.c - * - * Creation Date: 10/05/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - * Iterator Example - */ -#include "cmc/linkedlist.h" -#include -#include - -// Creates a linkedlist of integers -CMC_GENERATE_LINKEDLIST((ll, linkedlist, int) - -int main(int argc, char const *argv[]) -{ - // Create a new linkedlist - linkedlist *my_linkedlist = ll_new(); - - // Add elements to the linkedlist - for (int i = 0; i < 20; i++) - { - ll_push_back(my_linkedlist, i); - } - - // Iterate from the start (index 0) to the end (index count - 1) of the linkedlist - for (linkedlist_iter it = my_linkedlist->it_start(my_linkedlist); // Initialize iterator 'it' to the start of the linkedlist - !ll_iter_end(&it); // Conditional stop (until it is not at the end) - ll_iter_next(&it)) // Iterator goes one position forward - { - // Access the current element - int e = ll_iter_value(&it); - - // Access the current index (index is relative to all the elements in the iteration) - size_t i = ll_iter_index(&it); - - // Print linkedlist - - // Index is useful in situations like this - // If it is the first element - if (i == 0) - printf("[ %d, ", e); - // If it is the last element - else if (i == ll_count(my_linkedlist) - 1) - printf("%d ]\n", e); - // For elements at the middle - else - printf("%d, ", e); - } - - // Index can also be used to iterate over a certain portion of a collection - size_t limit = ll_count(my_linkedlist) / 2; - for (linkedlist_iter it = my_linkedlist->it_start(my_linkedlist); !ll_iter_end(&it); ll_iter_next(&it)) - { - // Access the current element - int e = ll_iter_value(&it); - - // Access the current index (index is relative to all the elements in the iteration) - size_t i = ll_iter_index(&it); - - // Print linkedlist up until limit - - // If it is the first element - if (i == 0) - printf("[ %d, ", e); - // If it is the last element - else if (i == limit - 1) // -1 because index is 0 based and we want half of the linkedlist - { - printf("%d ]\n", e); - break; - } - // For elements at the middle - else - printf("%d, ", e); - } - - // Going backwards - for (linkedlist_iter it = my_linkedlist->it_end(my_linkedlist); // Initialize iterator 'it' to the end of the linkedlist - !ll_iter_start(&it); // Conditional stop (until it is not at the start) - ll_iter_prev(&it)) // Iterator goes one position backwards - { - // Access the current element - int e = ll_iter_value(&it); - - // Access the current index (index is relative to all the elements in the iteration) - size_t i = ll_iter_index(&it); - - // Print linkedlist - // Note how the conditions for the first and last elements are simply swapped - // Because iterating backwards make the first element be the index count - 1 - // and the last one be the index 0 - - // If it is the first element - if (i == ll_count(my_linkedlist) - 1) - printf("[ %d, ", e); - // If it is the last element - else if (i == 0) - printf("%d ]\n", e); - // For elements at the middle - else - printf("%d, ", e); - } - - // You can also use iterators in a while loop - // But to do so you must declare the iterator struct outside the loop first - linkedlist_iter it; - - // You have three options: - // - Initialize it using the functions provided by the linkedlist [ my_linkedlist->it_start() and my_linkedlist->it_end() ] - // - Initialize it using the init() function (when the iterator is already allocated) - // - Initialize it using the new() function (allocates on the heap, pointers only) - - it = my_linkedlist->it_start(my_linkedlist); - it = my_linkedlist->it_end(my_linkedlist); - - // This is equivalent to it_start() - ll_iter_init(&it, my_linkedlist); - - // For pointers - // Also equivalent to it_start() - linkedlist_iter *iter = ll_iter_new(my_linkedlist); - - // The actual while loop - while (!ll_iter_end(iter)) - { - // Accessing elements - int e = ll_iter_value(iter); - size_t i = ll_iter_index(iter); - - // Print index and element - printf("linkedlist[%2" PRIuMAX "] = %2d\n", i, e); - - // Move iterator forwards - ll_iter_next(iter); - } - - // Send the iterator to the start of the linkedlist - ll_iter_to_start(iter); - - // Send the iterator to the end of the linkedlist - ll_iter_to_end(iter); - - // Backwards loop - while (!ll_iter_start(iter)) - { - // Accessing elements - int e = ll_iter_value(iter); - size_t i = ll_iter_index(iter); - - // Print index and element - printf("linkedlist[%2" PRIuMAX "] = %2d\n", i, e); - - // Move iterator backwards - ll_iter_prev(iter); - } - - // Certain iterators also allow you to modify the contents it is iterating over - // Exceptions are collections that depend of the current state of the element - // like tree-based collections and heap (collections that have some kind of ordering). - // You also can't change the keys of an associative collection - - // Change every element that is divisible by 2 to the number 7 - for (ll_iter_to_start(&it); !ll_iter_end(&it); ll_iter_next(&it)) - { - // Get a reference to the current value - int *r = ll_iter_rvalue(&it); - - if (r != NULL && *r % 2 == 0) - *r = 7; - } - - // Now print it to see the difference - for (linkedlist_iter it = my_linkedlist->it_start(my_linkedlist); !ll_iter_end(&it); ll_iter_next(&it)) - { - int e = ll_iter_value(&it); - size_t i = ll_iter_index(&it); - - if (i == 0) - printf("[ %d, ", e); - else if (i == ll_count(my_linkedlist) - 1) - printf("%d ]\n", e); - else - printf("%d, ", e); - } - - // Dispose the iterator called by ll_iter_new() - ll_iter_free(iter); - // Dispose the linkedlist created - ll_free(my_linkedlist); - - return 0; -} diff --git a/examples/linkedlist/linked_list_node.c b/examples/linkedlist/linked_list_node.c deleted file mode 100644 index f8139e6..0000000 --- a/examples/linkedlist/linked_list_node.c +++ /dev/null @@ -1,68 +0,0 @@ -/** - * linked_list_node.c - * - * Creation Date: 26/03/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ -#include "cmc/linkedlist.h" -#include -#include -#include - -CMC_GENERATE_LINKEDLIST((l, list, int) - -int main(void) -{ - list *l = l_new(); - - for (int i = 0; i < 97; i++) - l_push_back(l, i); - - // Add 99 after and 33 before every node where its data is divisible by 3 - for (list_node *node = l->head; node != NULL; node = node->next) - { - if (node->data % 3 == 0) - { - l_insert_before(l, node, 33); - l_insert_after(l, node, 99); - node = node->next; // skip 99 - } - } - - size_t s = 0; - for (list_node *node = l_head(l); node != NULL; node = l_next_node(node), s++) - { - if (node->prev == NULL) - printf("[ %d, ", node->data); - else if (node->next == NULL) - printf("%d ]\n", node->data); - else - printf("%d, ", node->data); - } - - printf("\n\n"); - - s = 0; - for (list_node *node = l_tail(l); node != NULL; node = l_prev_node(node), s++) - { - if (node->next == NULL) - printf("[ %d, ", node->data); - else if (node->prev == NULL) - printf("%d ]\n", node->data); - else - printf("%d, ", node->data); - } - - printf("\n\n"); - - printf("List Head: %d\nList Tail: %d\nList Count: %" PRIuMAX "\n", l->head->data, l->tail->data, l->count); - - assert(s == l->count); - - l_free(l); - - return 0; -} diff --git a/examples/list/README.md b/examples/list/README.md deleted file mode 100644 index 58049cf..0000000 --- a/examples/list/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# List examples - -* iterator.c - A complete example of the list iterator -* list.c - Example of using a list and its iterator. -* string.c - How to treat a list as a mutable string. diff --git a/examples/list/iterator.c b/examples/list/iterator.c deleted file mode 100644 index 2187110..0000000 --- a/examples/list/iterator.c +++ /dev/null @@ -1,198 +0,0 @@ -/** - * iterator.c - * - * Creation Date: 10/05/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - * Iterator Example - */ -#include "cmc/list.h" -#include -#include - -// Creates a list of integers -CMC_GENERATE_LIST(l, list, int); -typedef struct list list; -typedef struct list_iter list_iter; - - -int main(int argc, char const *argv[]) -{ - // Create a new list with an initial capacity of 100 - list *my_list = l_new(100); - - // Add elements to the list - for (int i = 0; i < 20; i++) - { - l_push_back(my_list, i); - } - - // Iterate from the start (index 0) to the end (index count - 1) of the list - for (list_iter it = my_list->it_start(my_list); // Initialize iterator 'it' to the start of the list - !l_iter_end(&it); // Conditional stop (until it is not at the end) - l_iter_next(&it)) // Iterator goes one position forward - { - // Access the current element - int e = l_iter_value(&it); - - // Access the current index (index is relative to all the elements in the iteration) - size_t i = l_iter_index(&it); - - // Print list - - // Index is useful in situations like this - // If it is the first element - if (i == 0) - printf("[ %d, ", e); - // If it is the last element - else if (i == l_count(my_list) - 1) - printf("%d ]\n", e); - // For elements at the middle - else - printf("%d, ", e); - } - - // Index can also be used to iterate over a certain portion of a collection - size_t limit = l_count(my_list) / 2; - for (list_iter it = my_list->it_start(my_list); !l_iter_end(&it); l_iter_next(&it)) - { - // Access the current element - int e = l_iter_value(&it); - - // Access the current index (index is relative to all the elements in the iteration) - size_t i = l_iter_index(&it); - - // Print list up until limit - - // If it is the first element - if (i == 0) - printf("[ %d, ", e); - // If it is the last element - else if (i == limit - 1) // -1 because index is 0 based and we want half of the list - { - printf("%d ]\n", e); - break; - } - // For elements at the middle - else - printf("%d, ", e); - } - - // Going backwards - for (list_iter it = my_list->it_end(my_list); // Initialize iterator 'it' to the end of the list - !l_iter_start(&it); // Conditional stop (until it is not at the start) - l_iter_prev(&it)) // Iterator goes one position backwards - { - // Access the current element - int e = l_iter_value(&it); - - // Access the current index (index is relative to all the elements in the iteration) - size_t i = l_iter_index(&it); - - // Print list - // Note how the conditions for the first and last elements are simply swapped - // Because iterating backwards make the first element be the index count - 1 - // and the last one be the index 0 - - // If it is the first element - if (i == l_count(my_list) - 1) - printf("[ %d, ", e); - // If it is the last element - else if (i == 0) - printf("%d ]\n", e); - // For elements at the middle - else - printf("%d, ", e); - } - - // You can also use iterators in a while loop - // But to do so you must declare the iterator struct outside the loop first - list_iter it; - - // You have three options: - // - Initialize it using the functions provided by the list [ my_list->it_start() and my_list->it_end() ] - // - Initialize it using the init() function (when the iterator is already allocated) - // - Initialize it using the new() function (allocates on the heap, pointers only) - - it = my_list->it_start(my_list); - it = my_list->it_end(my_list); - - // This is equivalent to it_start() - l_iter_init(&it, my_list); - - // For pointers - // Also equivalent to it_start() - list_iter *iter = l_iter_new(my_list); - - // The actual while loop - while (!l_iter_end(iter)) - { - // Accessing elements - int e = l_iter_value(iter); - size_t i = l_iter_index(iter); - - // Print index and element - printf("list[%2" PRIuMAX "] = %2d\n", i, e); - - // Move iterator forwards - l_iter_next(iter); - } - - // Send the iterator to the start of the list - l_iter_to_start(iter); - - // Send the iterator to the end of the list - l_iter_to_end(iter); - - // Backwards loop - while (!l_iter_start(iter)) - { - // Accessing elements - int e = l_iter_value(iter); - size_t i = l_iter_index(iter); - - // Print index and element - printf("list[%2" PRIuMAX "] = %2d\n", i, e); - - // Move iterator backwards - l_iter_prev(iter); - } - - // Certain iterators also allow you to modify the contents it is iterating over - // Exceptions are collections that depend of the current state of the element - // like tree-based collections and heap (collections that have some kind of ordering). - // You also can't change the keys of an associative collection - - // Change every element that is divisible by 2 to the number 7 - for (l_iter_to_start(&it); !l_iter_end(&it); l_iter_next(&it)) - { - // Get a reference to the current value - int *r = l_iter_rvalue(&it); - - if (r != NULL && *r % 2 == 0) - *r = 7; - } - - // Now print it to see the difference - for (list_iter it = my_list->it_start(my_list); !l_iter_end(&it); l_iter_next(&it)) - { - int e = l_iter_value(&it); - size_t i = l_iter_index(&it); - - if (i == 0) - printf("[ %d, ", e); - else if (i == l_count(my_list) - 1) - printf("%d ]\n", e); - else - printf("%d, ", e); - } - - // Dispose the iterator called by l_iter_new() - l_iter_free(iter); - // Dispose the list created - l_free(my_list, NULL); - - return 0; -} diff --git a/examples/list/list.c b/examples/list/list.c deleted file mode 100644 index 25ca5bb..0000000 --- a/examples/list/list.c +++ /dev/null @@ -1,78 +0,0 @@ -/** - * list.c - * - * Creation Date: 08/04/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ -#include "cmc/list.h" -#include - -CMC_GENERATE_LIST(l, list, int); -typedef struct list list; -typedef struct list_iter list_iter; - - -int main(int argc, char const *argv[]) -{ - // Create a list with internal capacity of 100 - list *my_list = l_new(100); - - // - push_front (index: 0) [Complexity: O(N)] - // - push (index: give) [Complexity: O(N)*] - // - push_back (index: count) [Complexity: O(1)] - // - // - pop_front (index: 0) [Complexity: O(N)] - // - pop (index: given) [Complexity: O(N)*] - // - push_back (index: count - 1) [Complexity: O(1)] - // - // *average - // - // Average list Input/Output: O(N) - - for (int i = 0; i < 200; i++) - { - // Add elements to the list - l_push_back(my_list, i); - } - - // Erase all values from the list - l_clear(my_list, NULL); - - // Now that list is empty, add only even numbers - for (int i = 0; i < 200; i++) - { - // Add even numbers to a given index. In this case they are being added - // to the end of the list (count index == push_back). With a condition - // of being even (i % 2 == 0) - if (i % 2 == 0) l_push_back(my_list, i); - - // If added is true, the element was added to the list - } - - // Iterator - list_iter iter; - int result, sum = 0; - size_t index; - - // Iterate over each element starting from the start (iter_new positions - // the iterator to the start of the list) until the end of the list. - for (l_iter_init(&iter, my_list); !l_iter_end(&iter); l_iter_next(&iter)) - { - // Here index corresponds to the position of the result relative to all - // other elements in the iteration. It is only a coincidence that the - // index here is the same as the result's position in the list. - index = l_iter_index(&iter); - result = l_iter_value(&iter); - - // Do whatever you want with result and index, e.g. - sum += result * index; - } - - // Release resources - l_free(my_list, NULL); - - return 0; -} diff --git a/examples/list/string.c b/examples/list/string.c deleted file mode 100644 index 7c7b20e..0000000 --- a/examples/list/string.c +++ /dev/null @@ -1,166 +0,0 @@ -/** - * string.c - * - * Creation Date: 08/04/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ -#include "cmc/list.h" -#include -#include - -CMC_GENERATE_LIST(str, string, char); -typedef struct string string; -typedef struct string_iter string_iter; - - -// Comparison function -int chrcmp(char a, char b) -{ - return (a > b) - (a < b); -} - -void print_str(string *str) -{ - // If the buffer is not completely filled, there will be at least one null - // byte in the end of the list's contents. This printf is possible but very - // dangerous as you might end up printing something else from memory until - // a null byte. - printf("%s\n", str->buffer); - - printf("Size: %llu\n", str_count(str)); -} - -int main(int argc, char const *argv[]) -{ - // How to treat a list as a mutable string without \0 at the end - char *example1 = "Lorem ipsum"; - char *example2 = "dolor sit amet"; - char *example3 = "consectetur"; - - string *my_str = str_new_from(example2, strlen(example2)); - - // Add a single character to the front of the list - str_push_front(my_str, ' '); - - // Add a sequence of characters to the front of the list - str_seq_push_front(my_str, example1, strlen(example1)); - - // Add a charater to the back of the list - str_push_back(my_str, ' '); - - // Add a sequence of characters to the back of the list - str_seq_push_back(my_str, example3, strlen(example3)); - - // Iterate through each letter and print it - string_iter iter; - str_iter_init(&iter, my_str); - size_t index; - char result; - - // Printing each character - for (str_iter_to_start(&iter); !str_iter_end(&iter); str_iter_next(&iter)) - { - putchar(str_iter_value(&iter)); - } - - printf("\n\n"); - - // You can also print it reversed - for (str_iter_to_end(&iter); !str_iter_start(&iter); str_iter_prev(&iter)) - { - putchar(str_iter_value(&iter)); - } - - printf("\n\n"); - - // Now remove the first letter supposing we don't know where it starts - index = str_indexof(my_str, ' ', chrcmp, true); - - if (index == str_count(my_str)) - { - // char not found... - // Treat error - } - - // Now that we know where the first word is, remove it, including the - // extra space. [from, to] are inclusive. - str_seq_pop_at(my_str, 0, index); - - // Print it once again - for (str_iter_to_start(&iter); !str_iter_end(&iter); str_iter_next(&iter)) - { - putchar(str_iter_value(&iter)); - } - - printf("\nString length: %lu\n\n", str_count(my_str)); - - print_str(my_str); - - // Removing last word. - // Finding last white space: - index = str_indexof(my_str, ' ', chrcmp, false); - - // Extract last word including white space - string *str_out = str_seq_sublist(my_str, index, str_count(my_str) - 1); - - if (!str_out) - printf("Could not extract string\n"); - else - { - // Pop white space - str_pop_front(str_out); - - for (str_iter_init(&iter, my_str); !str_iter_end(&iter); str_iter_next(&iter)) - { - putchar(str_iter_value(&iter)); - } - - printf("\nString length: %lu\n\n", str_count(my_str)); - - for (str_iter_init(&iter, str_out); !str_iter_end(&iter); str_iter_next(&iter)) - { - putchar(str_iter_value(&iter)); - } - - printf("\nString length: %lu\n", str_count(str_out)); - } - - // Free strings - str_free(my_str, NULL); - str_free(str_out, NULL); - - printf("\n----------------------------------------\n\n"); - - // Another example follows - // Using prepend, insert, append, remove and extract functions - string *str = str_new(100); - - str_seq_push_front(str, "Hello World!", 12); - - print_str(str); - - str_seq_push_at(str, "Awesome ", 8, 6); - - print_str(str); - - str_seq_push_back(str, " Indigo.", 8); - - print_str(str); - - str_seq_pop_at(str, 14, 20); - - print_str(str); - - string *str_res = str_seq_sublist(str, 5, 12); - - print_str(str); - print_str(str_res); - - str_free(str, NULL); - str_free(str_res, NULL); - - return 0; -} diff --git a/examples/multimap/README.md b/examples/multimap/README.md deleted file mode 100644 index 35dba30..0000000 --- a/examples/multimap/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Multimap examples - -* multimap.c - Basic examples of a multimap. diff --git a/examples/multimap/multimap.c b/examples/multimap/multimap.c deleted file mode 100644 index b959015..0000000 --- a/examples/multimap/multimap.c +++ /dev/null @@ -1,89 +0,0 @@ -#include "cmc/multimap.h" -#include "utl/foreach.h" -#include -#include -#include - -int intcmp(int a, int b) -{ - return (a > b) - (a < b); -} - -size_t inthash(int t) -{ - size_t a = t; - a += ~(a << 15); - a ^= (a >> 10); - a += (a << 3); - a ^= (a >> 6); - a += ~(a << 11); - a ^= (a >> 16); - return a; -} - -CMC_GENERATE_MULTIMAP(mm, multi_map, int, int); -typedef struct multi_map multi_map; -typedef struct multi_map_iter multi_map_iter; - - -int main(int argc, char const *argv[]) -{ - const int min = 1, max = 201; - multi_map *map = mm_new(50, 0.8, intcmp, inthash); - - printf("Multimap actual capacity: %" PRIu64 "\n", map->capacity); - printf("Adding items from %d to %d twice\n", min, max); - - for (int i = min; i < max; i++) - if (!mm_insert(map, i, i)) - printf("ERROR with %d:%d\n", i, i); - - for (int i = min; i < max; i++) - if (!mm_insert(map, i, i)) - printf("ERROR with %d:%d\n", i, i); - - printf("Multimap count : %" PRIu64 "\n", map->count); - printf("Multimap capacity : %" PRIu64 "\n", map->capacity); - printf("Multimap load : %lf\n", (double)map->count / (double)map->capacity); - - int64_t sum = 0; - - for (int i = min; i < max; i++) - sum += mm_get(map, i); - - printf("Sum (unique): %" PRId64 "\n", sum); - - CMC_FOR_EACH(mm, multi_map, map, { - printf( - "[%3" PRIu64 "] = { %3d : %3d }\n", - iter.index, - iter.curr_entry->key, - iter.curr_entry->value - ); - }); - - printf("Removing all items\n"); - - for (int i = min; i < max; i++) - if (!mm_remove_all(map, i, NULL)) - printf("ERROR with %d:%d\n", i, i); - - sum = 0; - - for (int i = min; i < max; i++) - sum += mm_get(map, i); - - printf("Sum: %" PRId64 "\n", sum); - - CMC_FOR_EACH(mm, multi_map, map, { - printf("[%2" PRIu64 "] = { %2d : %5d }\n", - iter.index, - iter.curr_entry->key, - iter.curr_entry->value - ); - }); - - mm_free(map, NULL); - - return 0; -} diff --git a/examples/multiset/README.md b/examples/multiset/README.md deleted file mode 100644 index ce656de..0000000 --- a/examples/multiset/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Multiset examples - -* multiset_operations.c - Demonstrates common multiset operations. diff --git a/examples/multiset/multiset_operations.c b/examples/multiset/multiset_operations.c deleted file mode 100644 index 01022d6..0000000 --- a/examples/multiset/multiset_operations.c +++ /dev/null @@ -1,122 +0,0 @@ -/** - * multiset_operations.c - * - * Creation Date: 01/08/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ -#include -#include -#include -#include - -CMC_GENERATE_MULTISET(ms, multiset, char); -typedef struct multiset multiset; -typedef struct multiset_iter multiset_iter; - - -struct pair -{ - char value; - size_t mul; -}; - -int charcmp(char a, char b) -{ - return (a > b) - (a < b); -} - -size_t charhash(char a) -{ - return a; -} - -void print_set(multiset *M) -{ - cmc_assert_not_equals(ptr, NULL, M); - - size_t S = ms_count(M); - - printf("%s : ", ms_to_string(M).s); - - if (S == 0) - { - printf("{ EMPTY SET }\n"); - return; - } - - for (multiset_iter it = M->it_start(M); !ms_iter_end(&it); ms_iter_next(&it)) - { - size_t index = ms_iter_index(&it); - char value = ms_iter_value(&it); - size_t mul = ms_iter_multiplicity(&it); - - if (index == 0) - printf("{ %c:%" PRIuMAX ", ", value, mul); - else if (index == S - 1) - printf("%c:%" PRIuMAX " }\n", value, mul); - else - printf("%c:%" PRIuMAX ", ", value, mul); - } - -} - -int main(int argc, char const *argv[]) -{ - struct pair mset1[4] = {{'a', 2}, {'b', 1}, {'c', 3}, {'d', 1}}; - struct pair mset2[4] = {{'c', 1}, {'d', 3}, {'e', 1}, {'f', 2}}; - - multiset *A = ms_new(20, 0.6, charcmp, charhash); - multiset *B = ms_new(20, 0.6, charcmp, charhash); - - for (int i = 0; i < 4; i++) - { - cmc_assert(ms_insert_many(A, mset1[i].value, mset1[i].mul)); - cmc_assert(ms_insert_many(B, mset2[i].value, mset2[i].mul)); - } - - printf("Given two sets A and B:\n"); - print_set(A); - print_set(B); - - multiset *U = ms_union(A, B); - printf("\nA UNION B:\n"); - print_set(U); - - multiset *I = ms_intersection(A, B); - printf("\nA INTERSECTION B:\n"); - print_set(I); - - multiset *DA = ms_difference(A, B); - multiset *DB = ms_difference(B, A); - printf("\nA - B:\n"); - print_set(DA); - printf("\nB - A:\n"); - print_set(DB); - - multiset *AB = ms_summation(A, B); - printf("\nA + B:\n"); - print_set(AB); - - multiset *BA = ms_summation(B, A); - printf("\nB + A:\n"); - print_set(BA); - - multiset *SD = ms_symmetric_difference(A, B); - printf("\nA SYM DIFF B:\n"); - print_set(SD); - - ms_free(A, NULL); - ms_free(B, NULL); - ms_free(U, NULL); - ms_free(I, NULL); - ms_free(DA, NULL); - ms_free(DB, NULL); - ms_free(AB, NULL); - ms_free(BA, NULL); - ms_free(SD, NULL); - - return 0; -} diff --git a/examples/others/README.md b/examples/others/README.md deleted file mode 100644 index edbe8f5..0000000 --- a/examples/others/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Other examples - -* book_store - A book store where its books are loaded onto a list from a csv file. The newly added ones go to a queue of featured books where old ones are removed to give place to new ones. You can find a book by looking up its ISBN using a treemap or traversing the treemap and find all ISBNs of a corresponding title. -* separate_header_source - Example of how to compile the header and source separately. -* for_each.c - Using the `FOR_EACH` macro. diff --git a/examples/others/book_store/book.c b/examples/others/book_store/book.c deleted file mode 100644 index 1922c32..0000000 --- a/examples/others/book_store/book.c +++ /dev/null @@ -1,14 +0,0 @@ -// Separated file for all book functions -typedef struct book -{ - int isbn; - char *name; -} book; - -book *new_book(int isbn, const char *name) -{ - book *b = malloc(sizeof(book)); - b->isbn = isbn; - b->name = strdup(name); - return b; -} diff --git a/examples/others/book_store/books.csv b/examples/others/book_store/books.csv deleted file mode 100644 index 3b5344f..0000000 --- a/examples/others/book_store/books.csv +++ /dev/null @@ -1,10000 +0,0 @@ -781298694,turpis a -816377929,convallis morbi -143047844,volutpat -656080250,nulla ac enim in tempor -472388906,sit amet turpis elementum ligula -904073564,augue -724298615,augue vestibulum rutrum -443939371,erat volutpat -103437850,convallis nulla neque libero -951429508,erat volutpat in congue etiam -750063230,sit amet eros -732184760,ac est lacinia -861466119,libero ut massa volutpat convallis -719747755,enim in tempor turpis -392577061,fermentum -288973280,hac habitasse platea dictumst morbi -712343121,dolor quis odio consequat varius -939028768,turpis nec euismod scelerisque quam -882813538,et ultrices posuere cubilia curae -724353174,cum -625031719,morbi non -269753149,ridiculus -492590970,adipiscing elit proin interdum mauris -249815457,diam -619223067,dapibus -267823778,sit amet -595696914,erat eros -192195435,odio cras -411522754,feugiat non pretium quis -415798664,magnis dis parturient -634810634,nullam molestie nibh in -376260892,ut -342896994,lobortis -873361865,justo pellentesque -976019797,erat eros viverra eget -380165606,consequat lectus in -531727123,eleifend luctus ultricies eu nibh -198596186,in sagittis dui vel -715766998,pellentesque -499200239,porta volutpat -782378960,rutrum nulla tellus -532857491,in tempus sit amet sem -967327991,ipsum praesent -850046210,justo etiam pretium iaculis justo -492404059,purus eu -589963234,duis faucibus accumsan odio -929642916,porta -901935769,quam pharetra -823292109,in libero -255617304,amet consectetuer adipiscing elit -468244134,turpis nec euismod scelerisque quam -752230147,ligula pellentesque ultrices -552003908,sapien sapien non mi integer -519402424,vestibulum rutrum rutrum -514838268,in leo maecenas -650676909,curabitur convallis -935402236,consectetuer adipiscing -281079363,sed vestibulum -780918842,in congue etiam justo -752824441,massa quis augue luctus tincidunt -973780486,ut massa volutpat convallis morbi -873210377,ut -646172860,justo sit amet sapien -243098462,amet diam in magna -533474969,maecenas -766909887,scelerisque -637062301,eleifend donec -682498157,augue vestibulum rutrum rutrum -432507917,neque vestibulum eget -739906015,adipiscing molestie hendrerit at vulputate -567432201,in libero ut -198958217,nullam porttitor lacus at -331681940,curae mauris viverra diam vitae -848097803,mi in porttitor pede justo -930785315,morbi non quam -514800259,vestibulum velit id -569362312,nonummy maecenas -628951588,vestibulum velit id pretium -220974764,turpis eget elit sodales -447189664,magnis dis parturient -317104225,enim sit amet nunc viverra -532395931,tincidunt lacus at velit vivamus -540781907,nulla mollis -933903611,arcu libero rutrum -294470798,aliquet at -598213468,maecenas ut massa -497471346,cursus id turpis integer -413218400,bibendum morbi non -493973555,lacinia nisi venenatis tristique fusce -947719197,lacus purus -996645376,at -692815342,ultrices -464250371,justo etiam -577172464,convallis morbi odio odio -505587015,felis donec semper -479847138,maecenas tristique est et -836315209,mi pede malesuada -944827691,quis -878951622,maecenas rhoncus -844207657,ipsum primis in -118740904,felis fusce posuere -317564944,natoque -777241608,vestibulum sed magna at nunc -525188593,quam suspendisse potenti nullam -909592224,eleifend -479491058,nonummy -675621646,quam fringilla rhoncus mauris enim -109372836,interdum eu tincidunt -542287660,eu -735653067,parturient -197692656,vestibulum ante -740368153,dolor sit amet -250171196,viverra pede -263510151,pharetra magna ac consequat metus -524412968,curabitur convallis duis consequat dui -747198482,mi pede malesuada -941189489,luctus et -266017957,quis tortor id nulla ultrices -812430086,porttitor pede justo eu massa -684293039,quam -917123597,bibendum felis sed -604476257,sit amet eros suspendisse -616318723,mauris -695760531,neque duis -154227898,hac -705843252,sapien cum sociis natoque -684609822,risus -491738521,habitasse -450232420,vestibulum -357464056,tortor sollicitudin -719272725,est donec odio -415210577,pede ullamcorper -532872414,neque sapien placerat ante -660888399,etiam pretium iaculis justo in -427123202,nulla -221590910,elementum -504152482,cras non velit nec -941484094,at -853808896,magna vulputate luctus -380801905,integer a nibh -876631371,sem mauris laoreet -634310798,montes nascetur -813654834,suspendisse -648145772,pellentesque ultrices phasellus -106587051,eget eros elementum pellentesque -748517304,in -538274723,mauris lacinia sapien quis -378882354,tempor turpis -573660969,iaculis congue -665884654,congue elementum in hac -255235522,nam ultrices libero non mattis -574324121,venenatis -591745708,sapien a libero nam dui -422473050,tempus vel -246466275,imperdiet -940519937,neque -369099664,nibh fusce lacus purus aliquet -122937393,amet lobortis sapien sapien -930552110,rutrum nulla nunc purus phasellus -180936275,curae -317699019,velit eu est congue -961226936,mauris -986788039,non interdum in ante -535158702,vestibulum eget vulputate ut -170436771,sociis natoque penatibus et -172416681,sed nisl nunc rhoncus dui -838969909,luctus rutrum nulla -545502752,sapien varius ut blandit -761261034,cubilia curae -118708670,quis turpis sed ante vivamus -846208904,vel nulla eget eros elementum -251309725,sed augue aliquam -317892937,accumsan tellus nisi -306453460,vitae ipsum aliquam -658845448,etiam vel augue -430562641,et commodo -614009462,diam id ornare imperdiet -757595026,vestibulum vestibulum -792127873,scelerisque -855548223,ut volutpat -479359832,neque vestibulum eget vulputate ut -822265905,iaculis diam erat fermentum justo -206554147,leo maecenas -934883326,erat vestibulum -371642463,in -388756641,pede -443063355,consectetuer -146773832,amet lobortis sapien sapien non -823379099,nascetur ridiculus mus -417517376,volutpat in congue etiam -688920735,felis sed lacus morbi -222263695,congue etiam justo etiam -164431112,sed tristique in tempus -980857218,vitae consectetuer -505746286,morbi odio odio elementum -630227089,luctus et ultrices -679017987,ac lobortis -202575297,quam fringilla rhoncus mauris -416613222,sollicitudin vitae -483324293,proin -721636874,ultrices -454706461,aliquam non mauris morbi -579370684,curabitur gravida nisi at nibh -807707033,pede justo -318123659,nulla tellus in sagittis -915519810,augue aliquam erat volutpat in -238813733,amet -947971990,libero rutrum ac lobortis vel -822391964,eu felis fusce posuere -252891733,morbi -923763627,sapien a libero nam -353413101,ligula in -689514104,odio elementum -468486392,magnis dis -292973232,nulla mollis molestie lorem -882916761,lectus aliquam -731379538,quisque ut erat -571574757,amet lobortis sapien sapien -467926762,faucibus orci luctus -125786779,praesent -127699708,dapibus -455486682,iaculis justo in hac habitasse -588290162,non interdum -186580303,parturient montes nascetur ridiculus -536532502,vitae nisl aenean lectus pellentesque -208457214,a suscipit nulla -310879623,sem -737237563,mauris non -824804797,luctus ultricies -778560957,nam nulla integer pede -640550087,aliquet at feugiat non -682009942,enim -798783895,orci mauris -683994411,est phasellus sit amet erat -892435141,ut tellus nulla ut -956741667,augue aliquam erat -258771777,faucibus orci -398836009,sapien urna pretium -359912265,nam tristique tortor -608987740,luctus et ultrices posuere -921954169,nunc nisl duis -369401498,suspendisse accumsan -416077978,pellentesque quisque porta -716834883,tristique tortor -849767588,potenti in eleifend -968892151,ornare -101309392,ut volutpat sapien -407705321,a odio in hac habitasse -189346379,sit amet nunc viverra dapibus -945368943,tortor sollicitudin -437129118,fusce congue diam -216372668,vehicula -884590931,maecenas tincidunt -554047841,eget -740514316,semper est -783482870,ultrices phasellus id sapien in -948558528,justo etiam pretium -609724986,suspendisse potenti nullam porttitor lacus -886571035,integer pede justo lacinia eget -140117502,phasellus sit amet erat -686644217,dis -140395222,et magnis -153670881,nisi nam ultrices -655744471,lectus aliquam sit -179210182,orci -898807466,fermentum justo -542394002,amet eros suspendisse accumsan tortor -500775367,ultrices erat tortor -556287435,mi integer ac neque -524582929,quis turpis sed ante -170034964,ac neque duis -997690406,pede libero quis orci -114391174,vel -153546336,at -577026920,sit amet -759462254,aliquam -891110353,rhoncus dui vel -482295756,quis turpis sed ante -206207684,fermentum justo -110518783,cras in -250740365,nunc donec quis -983949945,congue etiam -717478166,nisi nam ultrices libero -195838858,tortor eu pede -718908728,nonummy maecenas -688857372,ultrices erat tortor sollicitudin -419721311,integer -679796743,ligula suspendisse -334172963,donec quis orci eget -799642758,in -621202275,orci vehicula condimentum -183204698,sapien non mi integer -106128745,vulputate vitae -979913366,porta volutpat -995092961,placerat ante nulla justo aliquam -987378242,in -959080352,eget elit sodales scelerisque -481174409,ut nulla sed -345486353,amet eleifend pede -442377888,nibh quisque -996834422,dolor quis odio -338805904,ut odio cras mi pede -607059325,ipsum dolor sit amet consectetuer -216419747,lorem quisque -755243063,amet consectetuer adipiscing elit proin -245728713,justo pellentesque viverra pede -964412414,mauris non ligula pellentesque -867882512,magna bibendum imperdiet nullam orci -774575333,fermentum donec ut -886876554,mi pede malesuada -885650340,est risus auctor -744466137,parturient montes -536156490,orci -292689059,tortor id nulla -212287473,quam sollicitudin -291665617,congue etiam justo etiam pretium -368891182,viverra -155744417,tincidunt -920333901,pretium nisl ut volutpat sapien -368541971,libero ut massa volutpat -985009236,leo maecenas pulvinar lobortis est -517660513,nonummy maecenas -441465673,ac diam -657935733,ante nulla -824896407,phasellus in felis -838249931,in purus eu -541037411,congue risus semper -615996765,sit -762553035,sed ante -970079013,in felis -936388017,vel nisl -237753121,ultrices -495460874,semper est quam pharetra -334367439,ligula pellentesque ultrices phasellus -415765935,vestibulum velit id pretium iaculis -247596800,maecenas rhoncus -824368448,nulla -928715211,eros suspendisse accumsan tortor quis -413005991,erat nulla tempus vivamus -283200325,elementum eu -283181509,sed vel -942565642,ipsum integer a nibh -688581479,nec nisi -473424020,sed tincidunt eu felis fusce -680539375,non mattis -915115417,faucibus accumsan -857660873,sapien cursus vestibulum -996836340,augue luctus -459796964,nisi -409333746,id luctus nec molestie -931138232,eleifend -475048130,metus -794519738,ridiculus mus etiam vel augue -811799773,neque vestibulum eget -704027994,eget eleifend -289828918,sem mauris laoreet ut rhoncus -131448684,nulla sed accumsan -662688924,sapien ut nunc vestibulum ante -361141571,nisl venenatis -925300414,massa id nisl venenatis -354478527,vivamus vestibulum sagittis -336583525,adipiscing elit proin interdum -946483776,arcu sed augue aliquam erat -429013054,neque sapien placerat ante nulla -570376627,euismod scelerisque -283011583,vitae ipsum -985612475,rhoncus dui vel sem sed -378935184,sapien cursus vestibulum -508874921,dui proin -855898356,sollicitudin vitae consectetuer eget rutrum -820442160,nulla nisl -545397326,ac -240674103,odio -406033758,quisque porta volutpat erat -387080848,tincidunt -260253617,eget tempus vel pede morbi -311763894,massa id nisl -813194850,etiam justo etiam -245875714,nunc vestibulum ante -733078235,tellus in sagittis dui vel -173829273,dis parturient montes nascetur -368492263,elit sodales -846877025,blandit mi -532059441,mauris enim -106170084,consectetuer adipiscing elit proin interdum -280667889,elit sodales scelerisque -594686206,at velit vivamus -436975559,feugiat et -708860392,turpis a pede posuere nonummy -209629662,convallis nunc proin at -673068935,eu magna vulputate luctus cum -814586140,in hac habitasse platea dictumst -734083744,vivamus vestibulum sagittis -455120899,vestibulum sed -607999215,in imperdiet -317470790,sodales sed -189143046,hac -640396728,amet -535622018,nam congue -842106579,fermentum -908971227,id luctus -563241465,magna at nunc commodo -170049902,potenti nullam porttitor lacus at -731497429,dis parturient montes -721024083,proin at turpis a -122052301,blandit ultrices enim lorem -922326951,aliquet -339705159,luctus et -641344847,pretium nisl ut volutpat -525881001,porttitor lacus at turpis donec -811941534,eu sapien cursus vestibulum -382167376,luctus nec -668066332,nullam molestie nibh in -287222124,posuere felis -861061291,nam dui proin leo -468121169,mauris ullamcorper purus sit amet -734075187,in -597302237,mollis molestie lorem quisque ut -672270192,non mi integer -926054346,lacus morbi sem mauris -289776824,diam in -252193063,interdum venenatis turpis enim blandit -310055644,ut -777334978,hac -953096398,vestibulum -885067438,tempus sit amet sem -130225976,faucibus accumsan odio -964341229,lorem id ligula suspendisse -595986688,ac enim in tempor turpis -339792111,id massa id -962714875,amet -922400457,vestibulum rutrum rutrum neque -639187592,quis justo maecenas rhoncus -217737795,consectetuer adipiscing elit -721319335,nisl aenean lectus pellentesque eget -518032578,at -692187482,sed augue aliquam -369761897,sed interdum venenatis turpis -102764862,sit -602053883,bibendum felis sed -981462282,risus praesent lectus -272606121,etiam pretium iaculis justo in -482826618,tristique -159193951,orci mauris lacinia -117949879,posuere felis sed lacus morbi -731227843,nulla tempus vivamus -399075876,convallis tortor -356517567,ornare imperdiet sapien urna -861312333,rhoncus mauris -473467184,curae nulla dapibus dolor vel -798489429,erat volutpat in congue etiam -251653903,sit amet erat -274430071,elit proin interdum -377808314,erat tortor sollicitudin -298823032,vehicula consequat -687593772,penatibus et -971961311,ac leo pellentesque -328116863,eu -424905585,pede venenatis non sodales -517740967,sit amet sapien -787718111,turpis enim blandit -716501199,consequat -910844423,at -980490001,imperdiet et commodo vulputate -110443199,eget vulputate ut -746305402,pede ullamcorper -509662918,habitasse platea dictumst aliquam -164607165,porttitor -507409926,aliquam non mauris -901124427,at dolor -543537949,ut tellus nulla ut erat -484093598,posuere cubilia curae -207958415,gravida sem -301631241,porttitor pede -333531413,potenti nullam porttitor lacus at -867220019,neque vestibulum eget -448787830,non -549987740,justo -255414917,pede morbi porttitor -216914229,volutpat dui maecenas tristique -399896790,in congue -617724872,habitasse -985280573,cubilia curae -686374281,odio condimentum id luctus nec -840358971,erat eros -132679967,vestibulum eget vulputate ut -897029685,in ante -567154173,eu tincidunt -827855511,ligula nec sem -394633924,praesent id massa id nisl -372929662,consequat -612048742,fusce consequat nulla -819899911,pede -644138182,aenean -135101543,ullamcorper augue a suscipit nulla -191509872,dapibus dolor vel est donec -348790613,in faucibus -299390436,ligula nec sem -888732761,nec dui luctus rutrum nulla -443629968,magna ac consequat metus -673282588,vestibulum sit amet cursus -243240217,mauris laoreet ut rhoncus aliquet -563116574,augue aliquam erat volutpat -605566828,quis turpis sed ante -329421212,interdum in ante vestibulum -202663716,dictumst etiam faucibus cursus urna -797765438,et ultrices posuere cubilia -376802628,lectus pellentesque eget -145982474,phasellus in -883397460,pulvinar nulla pede -626975025,odio consequat varius integer ac -212500988,ut dolor morbi -458129335,ac nibh -288174338,tellus nisi -346423921,justo in hac habitasse -154922337,primis in faucibus orci -222547250,semper -560541411,lobortis vel -472383720,tellus -620738305,consequat in consequat ut -763017292,enim lorem ipsum dolor sit -722134865,nam -132902751,nisl -392009887,eu orci mauris lacinia sapien -201831631,dui vel sem sed -915479901,at nibh -731647169,interdum in ante -278559648,phasellus -325743179,in -223279998,duis bibendum morbi non quam -776679984,praesent blandit lacinia -600912239,fringilla rhoncus mauris -559008428,morbi a -935548117,vulputate elementum nullam -330907389,et magnis dis parturient montes -491948883,ullamcorper purus sit amet -365651357,enim leo rhoncus sed -529739167,fusce consequat nulla nisl nunc -790310781,ultrices -670967419,sodales scelerisque mauris sit -745998153,nulla -494766810,quam nec dui -611356326,ridiculus mus etiam -273990455,at diam nam tristique tortor -430901285,velit id -666845488,dui vel sem sed -828595404,iaculis congue -493524820,laoreet ut rhoncus -851474571,viverra pede -628269481,eget -923405470,lorem -779061735,ut nulla sed -993320046,dis parturient montes nascetur ridiculus -276411949,pede lobortis ligula sit -594323336,potenti -759555508,nunc rhoncus dui vel -337980554,lorem -791838435,id mauris -820149039,primis in faucibus -758436504,porttitor lorem id ligula -682291716,suscipit nulla -225297688,vel -536503315,rhoncus dui vel sem -299155752,justo eu -368570578,vestibulum aliquet ultrices erat tortor -869427220,pharetra magna vestibulum aliquet ultrices -415631260,vulputate luctus cum -155965384,et -607951919,id pretium -380454031,convallis eget eleifend luctus -929373424,aliquet -865812018,lorem ipsum dolor sit -445603076,tellus -913661219,justo in blandit -805921100,vel dapibus -197917213,turpis enim -335652124,ligula in lacus curabitur at -483579592,vel augue vestibulum rutrum -277732891,felis sed interdum venenatis -958497886,ante vel ipsum praesent blandit -265587351,nulla mollis molestie lorem quisque -907095288,ac tellus semper interdum -542382275,curabitur -375761001,risus praesent lectus vestibulum quam -431330810,cras pellentesque volutpat dui -376104776,enim in tempor turpis nec -856295836,adipiscing lorem vitae -649830545,pellentesque ultrices -456724927,urna pretium nisl ut volutpat -506243013,nisi at -363782231,ligula sit amet -765755219,fringilla rhoncus mauris -859656386,et ultrices -163600773,accumsan felis ut at -112309566,non ligula -555912082,enim in tempor turpis nec -943814060,vivamus vel nulla eget -864858627,volutpat -832203374,proin leo odio porttitor -186605016,sagittis nam congue -278386404,at velit vivamus vel nulla -131618233,duis ac nibh fusce -652205915,ante ipsum primis in faucibus -339181120,nunc proin at turpis a -781164881,sapien in sapien iaculis -472116524,molestie nibh in lectus -607636852,a ipsum integer a nibh -119614844,libero nam dui -477754647,elit sodales scelerisque mauris sit -525992874,faucibus accumsan -506589472,ac consequat metus sapien ut -299242238,condimentum curabitur in libero ut -797732851,lacus -533342047,arcu adipiscing molestie hendrerit -767612304,platea dictumst etiam faucibus cursus -325876208,porta -283708649,interdum venenatis turpis enim -901774416,nam tristique tortor -123441992,viverra eget -370602265,at turpis a -342894068,erat tortor -240390200,vestibulum aliquet ultrices -449941751,rutrum ac lobortis -421107011,nulla neque libero -590680018,sit amet -517151537,et -588686109,tortor duis -591817162,tempor convallis nulla -568985837,sollicitudin mi -246270911,suspendisse -221263815,at vulputate vitae nisl aenean -697910114,duis aliquam convallis nunc -578285347,lobortis -232964015,non mi integer ac -220581687,condimentum id luctus -189325194,magna -550272121,in lacus curabitur -876701321,justo eu massa donec dapibus -775446651,primis -942575481,nec nisi -328461076,malesuada -906480374,et ultrices -232533487,est donec odio justo -802553960,duis at velit eu -290097774,euismod -201920503,cursus vestibulum proin -732530524,vel sem sed -855619027,est lacinia nisi venenatis -383839580,fusce congue diam id -545502730,dis parturient montes -233226817,eu nibh quisque -900982758,suspendisse -677288934,iaculis -499954295,at -904754711,eget -246187383,purus phasellus -677759111,purus -229191749,fusce posuere felis sed lacus -398051278,faucibus orci luctus et ultrices -114635236,vestibulum -247836829,amet consectetuer adipiscing elit -602273233,enim -385500952,et tempus semper est quam -488656844,dignissim -315719705,id nulla ultrices aliquet maecenas -617924455,lectus aliquam -306312238,proin risus praesent lectus vestibulum -436328118,odio -903851558,nullam sit amet -843380995,metus sapien ut nunc -945027167,potenti -399584297,ligula sit amet eleifend -409219190,ipsum primis in faucibus -226226812,venenatis tristique fusce -156262453,donec odio justo -236942885,consequat -881723749,tristique tortor eu pede -175176367,diam vitae quam -106531562,luctus -600892333,ultricies eu nibh quisque -574834523,turpis sed ante vivamus tortor -115558896,imperdiet sapien urna -863101443,auctor sed -287235270,aliquet pulvinar sed nisl -350923237,porttitor pede justo -819236508,nulla quisque arcu -924011275,adipiscing elit proin interdum -828554103,odio porttitor id -561600254,sit amet erat nulla -680645959,elementum eu interdum -389878809,faucibus -189656744,penatibus et magnis dis parturient -773605817,pede libero quis orci -460058225,in blandit ultrices enim -172123815,blandit ultrices enim -540993416,quis lectus suspendisse -297480722,justo nec condimentum -911365765,sed -912530106,nam tristique tortor eu -240332723,purus -429119269,vivamus vestibulum sagittis -516103253,cursus id turpis integer -792267093,sed justo pellentesque -314453434,luctus -383383383,duis mattis egestas metus aenean -258436670,semper sapien a -391999560,risus dapibus -601714958,maecenas ut massa quis -652547225,eu interdum eu -173451007,vulputate -816571710,dapibus at -916352948,turpis -941823480,augue quam sollicitudin vitae consectetuer -261464762,est risus auctor sed -917950797,accumsan odio -819824712,mi in porttitor -541442034,mi in porttitor pede justo -645312371,sapien arcu sed augue -872390995,amet lobortis sapien -779660028,erat -237415042,donec odio justo sollicitudin -265457582,posuere metus -797249187,suscipit ligula in lacus curabitur -130690916,eros -222700732,odio curabitur -644200803,in felis eu sapien -755701657,dui nec nisi volutpat eleifend -799296499,eget eleifend luctus ultricies eu -963217849,est -777035052,ligula vehicula -221486930,leo odio condimentum id luctus -918024381,nulla tellus -104690256,pellentesque viverra pede -300528216,ultrices phasellus id sapien in -754495677,tristique in tempus sit amet -302676659,viverra eget congue eget semper -721911940,pellentesque ultrices phasellus -253083953,nec dui -763078846,in imperdiet -723128091,pede lobortis -248189246,lectus suspendisse potenti -718960693,aliquam erat volutpat in congue -309825615,praesent blandit nam nulla integer -616445640,eu magna vulputate -672259438,lacus morbi quis tortor id -462837754,vulputate vitae nisl aenean -608986424,aenean fermentum donec ut mauris -373043604,adipiscing -393155588,erat vestibulum -778955276,vestibulum rutrum rutrum -219038087,augue luctus tincidunt nulla -491542667,arcu libero rutrum ac lobortis -916248307,diam cras pellentesque volutpat dui -506518845,convallis nulla neque -778676382,faucibus cursus urna ut -121552386,eu -240812949,et ultrices posuere cubilia curae -941588109,et ultrices posuere -697795446,ipsum -451526057,enim in tempor -533021555,quis libero nullam sit -645771722,amet eros suspendisse -307848724,in porttitor pede justo -828248646,pretium quis lectus suspendisse -549401348,dui -246220483,amet -241821100,non sodales sed -450764998,eu magna vulputate luctus -993830075,et -228713310,id -454473013,ante ipsum primis in -150855164,pretium nisl -739964384,tempor convallis nulla neque -164145444,pellentesque quisque porta volutpat -835727156,sollicitudin vitae consectetuer eget -201747279,et ultrices -271342015,tincidunt eget tempus vel pede -796162200,justo eu -588642979,quis -410352918,eu mi nulla -461977001,donec ut dolor morbi vel -231565784,nulla -787712220,felis fusce posuere felis -885182188,habitasse -901690368,ante ipsum -422944367,nunc nisl duis bibendum felis -229302914,arcu libero -910119059,ut nunc -834121855,erat fermentum justo nec -286786113,morbi vel lectus in -508749783,vel sem sed sagittis -441375541,at lorem integer tincidunt -773063928,magna vestibulum aliquet ultrices -193938097,nisl nunc -834866722,ultrices libero non mattis -173253093,vestibulum ac -841101316,pulvinar lobortis est -549070762,in blandit -353531486,ut massa quis augue luctus -780952529,vestibulum ante ipsum -221684462,suspendisse accumsan tortor quis turpis -375538752,mi pede malesuada in imperdiet -694853347,volutpat erat quisque -671789534,faucibus orci luctus et ultrices -422452542,eleifend -533654053,condimentum -652572049,nisl aenean lectus -349152297,integer non velit donec -612859592,et tempus semper est quam -335291044,ac diam cras pellentesque -978819919,nibh -818501366,scelerisque mauris sit -646676648,dictumst maecenas -348435626,posuere cubilia curae duis -686148274,tincidunt nulla mollis -636075106,montes nascetur ridiculus mus -301046108,eros -973373267,sapien dignissim vestibulum vestibulum -230720602,leo maecenas pulvinar -283412313,luctus tincidunt nulla mollis molestie -834495579,quam -538101167,ornare -845114154,sapien -614240277,nisi nam -664387119,sit amet cursus id turpis -734687110,cubilia -476255193,pede ullamcorper augue -420900104,curabitur convallis duis consequat dui -726398230,eu magna vulputate luctus -636169401,auctor -800466170,parturient montes nascetur -589405228,lacinia eget tincidunt eget -291173381,platea dictumst -614269272,nisi at nibh -256568716,nisl -856547515,ac diam cras -667906873,cursus -320912686,phasellus sit amet erat nulla -329300596,sed lacus morbi sem mauris -576136128,congue elementum in hac habitasse -420716906,duis faucibus accumsan -744908556,metus -244342457,et ultrices posuere cubilia curae -810084363,montes nascetur ridiculus -444004263,orci mauris lacinia sapien -368548925,venenatis lacinia aenean sit amet -602442495,velit donec diam neque -231367681,quam sapien varius -600183927,suspendisse -646752138,tortor quis turpis sed -257315409,a libero nam dui -869335267,orci luctus et ultrices -514102606,proin leo odio porttitor id -278325679,enim blandit mi in porttitor -688590914,lobortis ligula sit amet -752822953,mauris morbi non lectus -555771306,magnis dis parturient montes -997876838,scelerisque -475394625,faucibus orci -540843891,suscipit a feugiat -457174639,rhoncus aliquet pulvinar sed -960341944,rutrum nulla nunc purus -928874090,non mi -207144670,nullam molestie nibh in -207936320,donec odio justo sollicitudin ut -776191219,odio odio elementum eu -866425295,lacus -766888281,tortor eu pede -790278586,nam -380755005,sodales sed tincidunt -839123776,turpis sed -486763901,iaculis justo in hac -953306387,diam -643053183,quam a odio -831671154,augue -317684757,morbi -492779052,integer tincidunt ante -970132383,volutpat erat -913967322,neque aenean -275199439,adipiscing lorem vitae mattis nibh -281305282,mauris viverra diam -339844168,lorem vitae mattis nibh ligula -797148880,vel ipsum praesent -793939708,eleifend donec ut dolor morbi -451761516,cubilia curae donec pharetra magna -947421148,lobortis sapien sapien non -344567172,aliquam augue -864978799,porta volutpat quam pede -385563146,tempus vivamus in felis eu -419756111,quam fringilla rhoncus mauris -228197638,in magna bibendum -287764883,id -441087514,adipiscing molestie hendrerit at -508845566,orci luctus et ultrices -278273733,vulputate justo -996911046,etiam faucibus cursus urna -407192892,fringilla rhoncus mauris enim leo -818078762,semper est quam -884256483,quisque porta volutpat erat -827343500,velit id -377074205,natoque penatibus et magnis dis -934774453,nisl nunc nisl duis bibendum -258238153,faucibus orci luctus et -217150259,diam nam -994422842,sapien cum sociis natoque -444572133,lobortis vel dapibus at -746630402,molestie hendrerit at -693223824,justo sit -260787305,vestibulum velit id -861657923,accumsan -482363148,sed nisl nunc -818671652,sapien arcu sed -873639264,proin risus praesent -890292337,est phasellus sit -229099730,morbi porttitor lorem id ligula -197378379,magna bibendum imperdiet nullam -656331573,diam neque -802985582,tempus sit -146839300,consequat ut -484171839,consequat nulla nisl -263391979,duis faucibus accumsan odio curabitur -188324730,pharetra -784705794,ante nulla justo aliquam -805171691,nibh -612972901,erat id mauris -764082396,platea dictumst morbi vestibulum velit -268260514,sem sed -913275414,lectus suspendisse potenti in eleifend -479802683,massa id nisl -376945775,dictumst etiam faucibus cursus -215226226,consequat -661816279,ipsum primis in faucibus -221079512,cubilia curae mauris viverra -763745415,interdum mauris ullamcorper purus sit -123016208,in lectus pellentesque at nulla -101386733,luctus ultricies eu nibh -313914335,augue vel accumsan tellus nisi -562580902,nibh quisque id justo sit -408877175,ridiculus -509556758,venenatis lacinia aenean sit -875481905,eleifend pede libero quis -862143100,in -387288630,duis -855923533,sapien a libero nam dui -155431999,mauris -923011500,et ultrices -431446692,cursus -440518711,ligula -943308270,dictumst maecenas ut massa -481786751,luctus tincidunt -788033247,justo -814268616,ut tellus -942803370,sapien iaculis congue vivamus -570299143,dictumst morbi vestibulum velit -825442077,ut blandit -296593102,vestibulum ante ipsum -135869462,vitae mattis nibh ligula -298036685,interdum mauris -715926546,sapien placerat -879977292,porttitor id consequat in consequat -925410349,in libero ut massa volutpat -460852139,eget elit sodales -111626459,scelerisque quam turpis adipiscing -203184372,donec quis orci -448039659,mauris ullamcorper purus sit amet -619709311,feugiat non pretium quis -249728399,penatibus et magnis dis -642950583,a libero nam -712124762,sociis natoque penatibus -169846157,eget tincidunt -724917969,dui -492925829,cras non velit -771869014,sapien arcu sed augue aliquam -390635384,commodo placerat praesent -678352182,sed nisl nunc -852905503,dolor sit amet -422990419,ultrices aliquet maecenas leo odio -137225599,sagittis nam congue risus -536406059,mus etiam vel -688346706,praesent blandit nam nulla integer -537445117,vestibulum -777118281,pede -444432166,arcu -582497873,habitasse platea dictumst aliquam augue -537536618,ligula nec sem duis aliquam -842669690,posuere cubilia -430230513,integer aliquet -819980576,ipsum primis in faucibus orci -212975547,varius ut blandit non -445183470,natoque -433703401,sapien -741604346,ipsum ac tellus -841874026,felis sed lacus morbi -755806592,maecenas leo odio condimentum id -528435146,habitasse platea -656554795,integer aliquet massa id lobortis -955625304,nunc viverra -398713048,amet diam -192031833,dictumst morbi vestibulum -388806111,maecenas tristique est et tempus -585425562,duis at -109785056,sed magna at -411214872,donec vitae -557819517,mauris lacinia sapien -321219491,enim -635399221,congue etiam justo -279226438,sem fusce consequat nulla nisl -212615544,ultrices libero non mattis -217901574,leo odio condimentum id -219518788,ipsum dolor sit -358663799,ipsum primis in faucibus -443031442,faucibus -755778242,placerat ante nulla -284668728,mattis nibh -726298837,vulputate ut ultrices vel augue -606477553,justo -883255553,est congue elementum in -889070020,rhoncus sed vestibulum sit amet -547033566,curabitur convallis -891558842,neque aenean auctor gravida sem -609351518,fermentum -966864953,cursus id turpis -195339731,vestibulum sit -205942161,consequat varius integer ac leo -584308569,amet nunc viverra -454807216,morbi a ipsum integer a -453671097,condimentum neque sapien placerat -388003041,risus semper porta -472336551,sit amet eleifend pede libero -456836049,pede libero quis orci nullam -735178500,ac tellus semper interdum -670787422,quis turpis eget elit -600217410,amet nulla quisque arcu libero -510476525,cum sociis -755864293,ipsum dolor -283942975,sed -691200601,eget semper -506534074,rutrum ac lobortis vel dapibus -462192249,condimentum neque sapien placerat -477484051,sociis natoque penatibus et -367151101,varius integer ac leo pellentesque -985546749,vulputate luctus cum sociis -238520982,sed magna at -487908705,vel accumsan -301349409,purus eu -733064844,elit sodales scelerisque mauris sit -289762236,molestie lorem quisque ut erat -618906269,nec dui luctus rutrum nulla -697800162,neque aenean auctor gravida -282497476,fermentum donec ut mauris -361165596,aenean auctor gravida sem -155395429,orci luctus -681916690,quis -497676722,lectus aliquam sit amet -187104132,lacinia -602945448,vel augue vestibulum rutrum rutrum -285529408,scelerisque -910208352,ut ultrices vel -216411550,vestibulum ante ipsum primis -715419844,eu -354310039,cubilia curae mauris viverra diam -807022566,amet -196400547,in quam -637565033,ac nulla sed vel enim -348476159,erat eros viverra -737191871,aliquam non -840321183,libero nullam sit -432930141,morbi non quam nec dui -105574241,a -668754572,tincidunt eu felis -638594292,nibh in -172583094,justo in blandit -481126042,urna ut tellus nulla -516452604,ac nulla -509119454,morbi non quam -602324597,eu nibh quisque id -346371666,vel augue -891040119,nibh in lectus pellentesque at -202342798,dictumst maecenas ut massa -454384560,morbi non lectus aliquam sit -502038947,adipiscing molestie hendrerit at vulputate -770674249,nascetur ridiculus -468798258,id sapien in sapien -889085614,potenti cras in purus eu -369177883,pede libero quis -221637922,platea dictumst morbi -626017363,cubilia curae donec -185153818,orci nullam -788599579,quis justo maecenas rhoncus aliquam -144863962,in faucibus orci -592424704,sagittis sapien -876907150,phasellus in felis -738765953,mattis odio donec vitae -609759014,amet justo -245974260,a suscipit nulla elit -480987901,ridiculus -175088546,lectus aliquam sit amet diam -214946157,tempor turpis nec -189653808,vel dapibus -996068512,rhoncus sed vestibulum sit amet -679127258,posuere nonummy integer non velit -107153740,arcu libero -869798106,tincidunt -987767876,nisl -966391584,lorem ipsum dolor sit -291375762,sodales scelerisque -384370923,luctus -861030972,varius nulla -613399543,varius nulla facilisi cras non -643861919,odio curabitur convallis duis consequat -272309148,nisl nunc -436788842,eu -141169299,nec dui luctus rutrum nulla -487013614,felis fusce posuere -882970171,habitasse -881704990,est -779020339,tortor risus dapibus augue vel -530290510,augue quam sollicitudin -687524547,tortor -934758197,cras in purus eu -192248450,congue eget -302520665,vel pede morbi porttitor -286957316,sapien iaculis -558443098,diam vitae quam suspendisse -677570110,nunc proin at -160002548,in felis -672473292,fringilla rhoncus -128031001,vivamus vestibulum sagittis sapien cum -636482812,aliquam lacus morbi quis tortor -258568878,id lobortis convallis tortor risus -771472930,ut nunc vestibulum ante -579210493,felis eu sapien cursus -743455693,dui proin leo odio porttitor -775149483,id mauris vulputate -440332987,sit amet -449425057,nunc viverra dapibus -687860046,dis parturient montes -901213632,et ultrices posuere cubilia curae -142798053,ante nulla justo aliquam quis -267746833,turpis a pede -985574759,lobortis ligula sit -746331508,enim leo rhoncus sed vestibulum -229020862,sem -644091471,volutpat dui maecenas tristique est -547386737,sed ante vivamus -433050731,nullam molestie nibh -128478393,ante -986493776,pede -611853100,sem -609849854,integer -812011157,lectus pellentesque -294748471,erat id -178516327,nec dui luctus -967404643,donec ut mauris eget massa -918643987,ut odio cras mi -307283229,lacus curabitur at ipsum -853169977,ante ipsum primis in -153189244,odio donec vitae nisi nam -125642459,diam cras pellentesque volutpat -739101636,ultrices posuere cubilia curae nulla -288125099,libero -136776621,dui -140431988,hac habitasse platea dictumst -719354228,ullamcorper purus sit amet -953538929,vel enim -625827060,aliquet massa -204674606,nec nisi vulputate -126999616,at -883797814,suspendisse -290442710,ante ipsum primis -614206326,phasellus id sapien in -575652137,pulvinar sed nisl -189178918,aenean fermentum donec ut -170349420,ultrices posuere -490091304,nisi at -178125841,odio porttitor id consequat -191438881,integer tincidunt ante vel -682188053,praesent -184460175,velit eu est -182138067,non mattis pulvinar nulla -891593847,a feugiat et -851065973,congue elementum in hac -709509442,elementum -982251816,auctor gravida -668048114,etiam justo etiam -482527586,vitae quam -953318780,lorem ipsum -761580925,et ultrices posuere -151627217,amet lobortis sapien sapien -230175070,in -650773479,eu sapien cursus vestibulum proin -677462367,sed ante vivamus tortor -357213954,lacinia eget -356671921,est congue -654632031,a suscipit -416684988,nibh in -692127721,congue risus semper porta volutpat -619808608,erat -649719536,lorem vitae mattis nibh ligula -782001372,et -575238348,non -412255841,porta -704079441,donec diam -586542936,suspendisse potenti in eleifend quam -230526115,nulla ut erat id -499194230,turpis -861077109,in consequat ut nulla sed -354228891,arcu sed augue aliquam erat -524033942,faucibus -936670661,velit donec diam neque vestibulum -544837626,at diam nam tristique -563762357,praesent id massa -833529937,vitae -130947499,vitae quam -929584171,fermentum -589242082,maecenas pulvinar lobortis -725055763,quisque -891383568,posuere felis -364170731,lobortis vel dapibus at -173212506,in -659335507,at -162463367,consequat nulla nisl nunc nisl -312926453,non ligula pellentesque ultrices -846748894,ut ultrices vel augue -613404528,vestibulum -397797547,quis justo -562087248,curabitur at -528065670,congue -341370168,habitasse platea dictumst aliquam -346920232,sociis -565000886,nullam molestie nibh in -852596070,platea dictumst aliquam augue quam -843121161,natoque -669589869,ut erat curabitur -529305575,semper est quam pharetra magna -676971811,tincidunt eget tempus vel -521349381,felis fusce posuere felis sed -713366560,lacinia sapien quis -976284716,non pretium quis lectus suspendisse -865316732,curae nulla dapibus -545923298,ac -312850474,ridiculus mus vivamus -545019754,ante nulla justo aliquam quis -115383281,libero non mattis pulvinar -597072784,justo etiam -608252843,rutrum at lorem integer tincidunt -642835119,sed sagittis nam congue -151521004,donec -544266202,diam -733037721,nunc commodo placerat praesent -216864029,libero rutrum -280680862,phasellus sit amet erat -499470571,at ipsum ac tellus semper -772052280,integer tincidunt -738439951,risus dapibus augue -320908868,vestibulum -503950177,penatibus et magnis dis parturient -461309121,platea dictumst maecenas ut -979107212,nulla sed accumsan felis -425376739,ut mauris eget massa -734625018,erat -278151470,scelerisque quam -383803952,praesent lectus -473210999,cubilia curae donec -481272218,in -370079972,in lacus curabitur at ipsum -883562391,lacinia eget tincidunt -743036766,ligula suspendisse ornare consequat -439185126,et tempus semper est quam -379585279,vestibulum ac -316769002,quam pede lobortis -460271011,augue aliquam erat volutpat -227073590,mi -115307409,ipsum -320878245,curae duis faucibus accumsan odio -360795456,curae mauris viverra -200100595,justo eu massa donec -647640214,leo odio porttitor id consequat -833008968,iaculis justo in -903929029,est quam pharetra magna ac -340200367,ipsum primis in -805919088,leo -367329410,suspendisse potenti cras -159600715,aliquet massa -661495481,amet turpis elementum -476584129,duis bibendum -369243356,tristique in tempus sit -319138663,felis eu sapien cursus vestibulum -785857525,non quam nec dui -267502881,adipiscing lorem -604011475,donec pharetra magna vestibulum aliquet -476899643,massa donec dapibus duis -914014991,at velit vivamus -605922139,dapibus -892357725,nisi eu -202850171,nam nulla -469242548,tristique in tempus sit amet -429296743,adipiscing molestie hendrerit at vulputate -731701682,nulla ultrices -166078258,id turpis integer aliquet massa -516102953,at velit -496598641,metus vitae ipsum aliquam -799088444,mauris non ligula -627089672,libero rutrum ac lobortis vel -809501609,laoreet -215056397,aliquam non mauris morbi -632072542,dui -785995051,volutpat convallis morbi odio -619396770,magna ac consequat metus sapien -733826187,consequat metus sapien ut -557141916,amet sapien dignissim vestibulum -729727741,ut erat curabitur -120353594,vivamus -433517861,eget eleifend luctus ultricies eu -215411188,erat curabitur gravida -594424497,nunc donec quis orci -816000958,interdum mauris ullamcorper purus sit -215792718,lacinia erat vestibulum sed -133759963,quam fringilla rhoncus mauris -145990057,blandit lacinia erat vestibulum sed -711118003,pulvinar -545932236,eleifend luctus -698298535,dolor sit amet consectetuer -485684358,integer tincidunt -890470305,in congue etiam justo -860718191,ante vivamus tortor duis -297597398,nulla nisl -194397457,sollicitudin mi -179791369,volutpat convallis morbi odio -798606399,adipiscing -632651492,maecenas -511200585,neque vestibulum eget vulputate -601485229,consectetuer eget rutrum at -266478256,vivamus in -264412464,nulla quisque arcu libero -814819322,amet erat nulla -890044809,orci -167895190,augue a suscipit nulla elit -798432280,congue elementum in hac habitasse -401196856,ipsum aliquam non mauris morbi -467731218,dolor sit amet consectetuer -385843663,pede justo -799630417,id -281985777,in faucibus orci luctus -978763001,eget -231926405,iaculis diam -193218861,arcu adipiscing -769756581,elementum pellentesque quisque porta -360518829,pretium nisl ut -999556558,donec diam neque -271730951,mauris non ligula pellentesque ultrices -819378141,et ultrices posuere cubilia -316714369,vel accumsan tellus nisi -459876048,quam -102344051,donec ut mauris eget -651609107,amet -794676507,habitasse platea dictumst morbi -824087923,sed nisl nunc -231184851,ut blandit -792311379,volutpat dui maecenas tristique est -873227681,in tempor turpis nec euismod -840543118,tellus -159816128,accumsan -359768772,sapien placerat ante -698384433,magna bibendum imperdiet nullam -110446288,nam -554830506,eu -243224793,in -813955269,vivamus vel -122327514,lacus -721522873,leo maecenas pulvinar lobortis -235883108,amet nulla quisque arcu libero -230307736,curabitur -138630787,posuere cubilia curae mauris viverra -670011463,habitasse platea dictumst -670976435,ut volutpat -184098583,vivamus tortor duis mattis egestas -755427800,convallis nunc proin at -606518470,leo -900920707,vivamus in felis eu -750273333,consequat lectus -734933256,mi in porttitor pede -662417597,nulla integer -585781028,dolor quis odio consequat varius -681453349,nullam -799880853,vulputate nonummy maecenas -944409360,sagittis sapien cum sociis natoque -547272259,curabitur -980422137,nisi -595780270,consequat in consequat -753754853,semper -405123341,justo maecenas rhoncus aliquam -901223353,sodales scelerisque mauris sit -386532412,convallis -282474062,eros -721277977,parturient montes -413211647,est lacinia nisi -792946792,vivamus vestibulum sagittis -984384828,tortor -126380122,augue quam -138624655,non velit -778588930,volutpat in congue etiam -888032082,sed -604497572,et ultrices posuere -150108368,est donec -605325194,quam fringilla -398399834,at -963653170,vestibulum ante ipsum primis in -531411087,in faucibus orci luctus -820326048,magna vulputate luctus cum -522965721,ut at dolor -667292026,vivamus vestibulum -667333994,ipsum aliquam non -885417325,amet cursus -818795731,vestibulum -491108884,purus -826187745,a feugiat -712132418,sodales -299636109,varius nulla facilisi cras non -297233726,pharetra magna ac consequat -634723609,ut tellus nulla ut -589202660,pretium iaculis -918452854,aliquam convallis nunc -730553379,quis turpis sed -699905334,at -533126333,aenean lectus pellentesque eget nunc -673159898,sit -239550426,sem praesent id massa id -782993724,in -769824282,enim -549898600,convallis eget eleifend luctus ultricies -357483502,gravida sem praesent id massa -587813192,aliquet massa -444575355,quam fringilla rhoncus mauris -700841012,dictumst etiam faucibus -260876523,congue risus -532172443,eget nunc donec quis -201249986,semper sapien a -224380839,dapibus augue vel -736016499,volutpat -982044284,vel augue vestibulum -283454699,eleifend quam -307837019,dui vel sem -672465726,non velit nec nisi vulputate -565303469,volutpat dui maecenas tristique est -527879208,natoque penatibus et magnis dis -396006325,congue vivamus -518580062,turpis integer aliquet massa id -536101515,dapibus -670256798,hac habitasse platea -318341499,non -740102185,mauris eget massa tempor convallis -404438024,nulla sed vel enim sit -399734825,odio -712561656,in blandit ultrices -899782776,pretium -910557820,imperdiet -343042877,massa donec dapibus duis -339712337,pede -832665311,at diam nam tristique -262636898,morbi a -525397759,pulvinar nulla pede -681321800,morbi sem -271511436,lorem ipsum dolor sit amet -379615553,ipsum primis in faucibus orci -107456917,ac -308273061,eget -905864922,libero rutrum ac -516432173,magna vestibulum aliquet ultrices erat -448985110,ipsum integer a nibh -718271326,sed interdum venenatis turpis enim -781885845,vel sem sed sagittis -179523347,mattis pulvinar nulla pede ullamcorper -338618216,primis in faucibus orci luctus -255125578,in -424403519,lectus pellentesque at nulla suspendisse -323540521,tempus vel pede morbi -256799309,vel augue -949830534,metus -344574893,aliquam lacus -764867519,blandit mi in porttitor pede -721743475,eu mi -205575029,adipiscing lorem vitae mattis -179619571,massa volutpat convallis morbi -201285694,phasellus in felis -868940616,lobortis vel -705607855,hendrerit -526503221,pharetra magna vestibulum aliquet ultrices -651089036,vulputate ut ultrices -836784644,odio odio elementum eu -110629962,pretium quis lectus -624259003,pulvinar sed -790074214,ut erat curabitur gravida nisi -455211319,habitasse -718682698,amet sapien dignissim vestibulum -148985130,non -111330186,amet consectetuer adipiscing elit proin -730375938,proin eu mi nulla -867967269,sed magna -320405624,sapien placerat ante nulla -506603114,quis augue luctus tincidunt -601102595,justo sollicitudin -625142377,aenean sit amet -576392068,suscipit ligula -501524635,aliquet ultrices erat tortor -810147012,justo pellentesque viverra -247431756,leo odio -372331233,dapibus -664969016,pede -764074585,mi nulla ac -188933379,libero nullam -691993430,vivamus metus arcu adipiscing -813793875,nascetur ridiculus -908102066,urna ut tellus -353247937,enim -204588602,curae nulla dapibus dolor vel -900554184,orci pede venenatis -310559482,neque libero convallis eget eleifend -150286436,donec -766028451,nulla eget -613467612,ut dolor -775437426,sapien cursus vestibulum proin eu -245153055,ligula -521561860,in hac habitasse platea dictumst -867232626,pede posuere -897382502,quisque arcu libero rutrum ac -525913194,non -186799841,semper porta -293608991,primis in faucibus orci luctus -632372422,blandit non interdum -717901218,iaculis justo in hac -158238557,nullam molestie nibh in -397605100,justo etiam pretium iaculis justo -257730732,curabitur at ipsum ac tellus -356947931,nonummy integer -546370742,urna pretium -755792097,venenatis turpis -985947825,mattis pulvinar nulla pede ullamcorper -945765632,donec ut dolor morbi -802305245,morbi a -142602939,vitae ipsum aliquam non mauris -510719000,in -625390091,enim in tempor turpis -215152896,ipsum -123066460,pede -536384400,ipsum aliquam non -353328226,rhoncus sed vestibulum sit amet -445688861,mauris laoreet ut -497980247,porttitor lacus at turpis donec -519370111,mauris -193852374,ultrices libero non mattis -826606611,laoreet ut -917357399,elementum -586455730,quisque -524550571,duis at velit eu est -801923780,lectus pellentesque at nulla -499063773,blandit nam nulla -774839808,nisi nam ultrices -580507539,nisl duis bibendum felis sed -103187032,tincidunt nulla mollis molestie lorem -382764952,rutrum at lorem -203747596,interdum mauris ullamcorper -747093068,ipsum primis in faucibus -994932185,interdum eu tincidunt in -734990675,est et tempus semper est -203696207,nunc viverra -316374409,ut erat -567286643,lacus -608719205,sit amet nunc viverra dapibus -792936171,porttitor lorem id ligula suspendisse -155332793,hac -127705402,sit amet nunc viverra dapibus -731316705,vulputate luctus cum sociis natoque -577203275,lacus morbi quis tortor id -685099190,suspendisse accumsan tortor quis -156463119,sit amet -648564866,egestas metus -861630254,risus auctor sed tristique -178385537,diam neque vestibulum -670688080,tincidunt eu felis fusce posuere -793702298,rhoncus aliquet pulvinar sed -841217473,porttitor -283078255,sed nisl nunc rhoncus dui -808101997,cras -275079301,mattis pulvinar nulla -180029275,maecenas ut massa -597104494,tincidunt nulla mollis molestie lorem -579560501,quisque erat eros viverra -235783010,lorem quisque ut erat -976815800,elementum pellentesque quisque porta volutpat -205836126,cubilia -605911851,vulputate vitae nisl -724142270,risus dapibus augue -494076679,diam vitae -934858216,lacinia eget tincidunt eget -933000284,velit eu est -773646018,hendrerit at vulputate -271127019,aliquet ultrices erat tortor sollicitudin -952780850,metus aenean fermentum donec -451650405,turpis nec -992462821,ante ipsum primis -781401896,viverra diam vitae quam -932066592,quam pede lobortis ligula -795573289,pellentesque eget nunc donec -670802879,blandit mi in porttitor pede -846286717,morbi non lectus aliquam sit -579265943,mus -968619914,fermentum donec ut mauris eget -147519674,sed sagittis -202140853,ligula nec sem duis aliquam -635348700,eu sapien cursus vestibulum -713902978,nisl nunc nisl duis -784818921,in tempor turpis nec euismod -244036892,luctus et ultrices posuere cubilia -286389667,ut nulla sed accumsan felis -487023353,donec ut mauris -839158824,at -463344566,volutpat in congue etiam -883289314,risus auctor sed -397543085,morbi non -427189256,felis -128602341,pede venenatis non sodales -187735035,in -288145119,rutrum nulla -389969129,pellentesque volutpat dui maecenas tristique -322062764,at turpis -702633866,condimentum curabitur in libero -152319807,donec ut -278450642,varius -443465041,ultrices mattis odio -475936306,dui -353058937,eu tincidunt in leo maecenas -479674027,justo etiam -454445413,etiam -374879260,mauris enim -107098175,sapien sapien non mi integer -485729239,massa id -197654662,convallis -821523719,morbi ut -190113063,in hac habitasse platea dictumst -141973689,nec dui -731557757,sed augue aliquam -263144280,dapibus -878880149,volutpat sapien arcu sed augue -159922933,nulla facilisi -769016692,in hac -668193156,enim leo rhoncus sed vestibulum -918759640,volutpat sapien arcu sed augue -984500262,nisi nam ultrices libero -226666041,a nibh in quis -555040576,dui -488692625,aliquet pulvinar sed nisl nunc -963165287,a -176495570,id mauris vulputate elementum -924053272,maecenas pulvinar lobortis est -213393876,amet cursus id turpis integer -577818092,a -721590447,nibh in -268691858,fusce consequat nulla -108622923,at -989394142,dictumst -360698306,libero quis -254762635,nisi -667685057,magnis dis parturient montes nascetur -244393597,mi nulla ac -977764868,morbi quis tortor -118286851,neque -725832368,sapien cum sociis natoque penatibus -318945702,dapibus duis at velit eu -625041559,praesent blandit lacinia erat vestibulum -791623713,est -403855916,velit -152462163,aliquam lacus morbi quis tortor -586624962,varius integer ac leo -179709749,libero rutrum ac lobortis -268160359,mus etiam vel augue vestibulum -975526141,volutpat convallis -372688460,penatibus et magnis dis -791157743,faucibus orci luctus et -220239609,erat -612449361,leo pellentesque -698262192,pulvinar lobortis est phasellus sit -975634997,felis -249530112,sagittis dui -590019680,semper -254613059,sagittis dui -254652713,vestibulum quam sapien -255881118,quis lectus -288385654,in consequat ut nulla -654692006,vestibulum ante -904468944,consectetuer adipiscing elit proin risus -129221196,duis -914634526,a ipsum integer a nibh -348931017,vel nulla eget eros elementum -177028713,aenean lectus -488730161,erat tortor sollicitudin -258223217,luctus cum sociis natoque -813092054,eu tincidunt in -931186665,vitae nisl aenean -430234133,odio donec -727758967,molestie sed -933242696,eget massa -750429343,erat -680954887,mauris lacinia sapien quis libero -745779309,elementum pellentesque -513035766,cubilia curae -748385067,non -664958115,etiam faucibus cursus urna -548775251,adipiscing molestie hendrerit at -746815554,quam turpis adipiscing -470466930,eget eros elementum pellentesque quisque -945376000,in ante vestibulum ante -812031312,sed tristique in tempus sit -534848816,ultrices mattis odio donec -359982334,in -979036799,consequat -317840436,justo -924979951,ridiculus mus etiam -447436949,odio cras mi pede malesuada -899341757,natoque penatibus et -721259021,amet sapien -187950833,dui -347737248,blandit lacinia erat vestibulum -882327605,id justo sit amet sapien -570564201,cum sociis -699921375,sollicitudin vitae consectetuer eget rutrum -507897885,justo maecenas -819447018,cubilia curae donec -834664237,pellentesque eget nunc donec -126034161,aliquam quis turpis eget -457589632,aenean auctor gravida -118778907,augue quam sollicitudin vitae consectetuer -751449217,sapien -209678746,platea dictumst morbi -505295758,leo odio porttitor -502373116,turpis a pede -933029958,in tempus -877214129,lacinia nisi venenatis -862356225,in hac habitasse -783809132,quam pharetra magna ac -614306059,nisi vulputate nonummy -411087957,pede lobortis ligula sit amet -836937091,etiam faucibus cursus urna -518989510,pede justo eu massa -176579335,mi integer ac -230043758,in -647131563,bibendum felis sed interdum -228116055,etiam pretium iaculis justo in -729328593,orci luctus et ultrices posuere -695190590,praesent blandit -478348876,sed ante vivamus -331452148,sed tristique in -121648095,suspendisse ornare consequat lectus in -972723954,praesent blandit nam nulla integer -931842048,ac diam cras pellentesque -612815906,ac enim in tempor turpis -201704009,faucibus orci luctus -610512186,porta -110825362,urna ut tellus nulla -493967162,pulvinar lobortis est -945880008,cras -152745014,malesuada in -958242048,et commodo vulputate justo -318474754,varius ut -482721990,lectus aliquam sit amet diam -768898890,ligula nec sem duis aliquam -179557195,massa tempor convallis nulla -475733293,vel ipsum praesent blandit lacinia -672303710,ut nunc -370867541,vulputate -973829115,aliquet ultrices -692654076,consectetuer eget rutrum -155539443,metus arcu -207107432,leo -457282180,sapien -292443904,neque libero -314908848,duis mattis egestas metus aenean -559146440,elit -122551687,auctor sed -480449464,amet -885684326,sapien a -979972604,curabitur in -364008963,metus vitae ipsum aliquam -104316944,vulputate luctus -161502356,pretium iaculis diam erat -409543070,aliquam lacus morbi quis tortor -612154247,consequat nulla nisl nunc nisl -248428965,at -756648058,augue a -805874106,accumsan tortor -302838716,quis odio -622501080,integer non velit donec diam -969366179,turpis a pede posuere nonummy -245899524,eu felis fusce posuere felis -539495904,vestibulum ac est lacinia -151858840,consequat varius integer ac -341297329,quam pharetra magna ac -290499598,tellus nisi eu orci mauris -159571984,nulla -434658369,porta volutpat -539537896,viverra eget congue eget -512502797,morbi odio -794088082,turpis -882656174,sagittis nam congue risus semper -884636587,eu -994911900,adipiscing elit proin interdum -480751687,leo -894117489,mauris -428071894,vestibulum ante ipsum -715014795,iaculis diam -134375469,dictumst morbi vestibulum velit id -503892140,tortor duis mattis egestas metus -517152996,lacinia -149977255,turpis adipiscing lorem vitae mattis -861180786,rutrum neque aenean auctor gravida -350542862,pulvinar sed nisl nunc rhoncus -935594606,pede ac diam -293517931,dictumst morbi vestibulum velit -761625861,in consequat -158468029,pretium iaculis justo in -357552248,diam id ornare imperdiet -979584161,sapien cursus -914904140,etiam justo etiam pretium -690084398,vestibulum -156112919,eros suspendisse accumsan tortor quis -214960187,mauris ullamcorper purus -795778362,non sodales sed tincidunt -588079513,interdum venenatis turpis -898358752,massa -846486427,luctus et ultrices posuere -872325184,sit amet -265193738,id turpis integer aliquet massa -834534985,ridiculus mus vivamus -364453946,quam sollicitudin vitae consectetuer -527245642,magna at nunc commodo -370178089,vel sem -580824449,ridiculus -874976347,non pretium quis lectus suspendisse -630522288,etiam vel augue -954578988,nec molestie -126165073,suspendisse potenti -243745156,consectetuer eget rutrum at lorem -626270204,interdum -486333298,condimentum id luctus nec -747456512,phasellus -361388735,aenean sit amet -125096127,gravida nisi -315326665,augue vestibulum -137144075,faucibus orci luctus -910321522,porttitor lorem id ligula -164133148,vitae mattis nibh ligula -296044516,maecenas tristique est et -371486267,lorem ipsum -124116102,vestibulum proin eu mi nulla -801032924,vestibulum sit amet cursus id -528110797,ipsum ac tellus semper interdum -148241059,hac habitasse -852595505,blandit lacinia erat -438034546,luctus et ultrices posuere -211016205,eget nunc donec quis orci -162955965,lectus pellentesque -470937798,interdum in ante vestibulum -772483896,velit nec -769978871,primis in faucibus orci -518954459,integer ac -771519427,odio justo sollicitudin ut suscipit -217419423,ultrices enim lorem ipsum -291020131,proin at turpis -887762435,amet -929997198,at dolor quis odio -981456067,ut -313364104,vulputate ut ultrices vel augue -938003061,quis odio consequat varius -223363403,ut mauris eget massa tempor -619041281,interdum -731078219,ipsum primis in faucibus -277919403,felis -204787939,curae -856694371,hac habitasse platea dictumst morbi -736505759,imperdiet et commodo -796777319,platea dictumst morbi vestibulum velit -497063724,est phasellus -491894363,vivamus metus -586363990,ut suscipit a feugiat et -647319092,ipsum dolor sit amet consectetuer -406713635,eros viverra -827236108,dis parturient montes -275251950,pede -793646783,sed vestibulum -367718058,ligula sit amet eleifend pede -266404465,interdum in ante vestibulum ante -137511880,platea dictumst morbi vestibulum -182827380,suspendisse potenti nullam porttitor lacus -916442991,ultrices erat tortor -557752110,id ornare -145946822,in est risus auctor sed -901134786,mauris laoreet -946530628,volutpat sapien -110601069,vivamus tortor -261810933,consequat -911774967,vulputate -279533358,ipsum aliquam non -368816888,est risus auctor sed -842240542,potenti nullam -504611122,et magnis dis parturient -312867708,nisl duis ac -452756718,luctus -808222531,quisque arcu -522293642,donec ut dolor -391583678,eu nibh quisque id justo -102346112,eu interdum -861240307,eu est congue -662642393,vel lectus in quam fringilla -408714616,accumsan tortor quis turpis sed -783601729,sagittis sapien -654037338,commodo vulputate justo in -991192363,erat volutpat in -583528549,sem sed sagittis -565692583,sit amet -305455044,sit amet justo -908044204,aliquet maecenas -806691076,in -662221942,blandit nam -951469248,ultrices mattis odio donec vitae -884894719,consequat morbi a ipsum integer -420046738,molestie hendrerit at vulputate -133581915,libero quis orci -333808963,eu -556861287,eget massa tempor -658962825,volutpat -992673147,est lacinia -828389087,in libero ut massa -507838025,leo maecenas pulvinar -267124773,mauris morbi non lectus -881751825,ante nulla justo aliquam -257939687,libero quis orci nullam molestie -917536398,sed vestibulum -544874572,nisl venenatis lacinia aenean -791522693,id -194503966,convallis eget eleifend luctus ultricies -765741925,at velit -170529985,elementum ligula -828426618,suspendisse potenti in eleifend quam -796785198,vel augue vestibulum ante -426688400,morbi -388359353,pulvinar lobortis est -984709408,velit vivamus vel -576455996,nec condimentum neque -478374456,rhoncus -553047396,nullam orci pede venenatis -316773240,turpis integer aliquet -626529203,nec nisi vulputate -749344999,vel nisl duis ac -639528982,metus aenean fermentum donec -706482740,odio in hac habitasse -400792622,cubilia curae donec pharetra -834435750,nascetur ridiculus -303773074,mus etiam vel augue -671247105,faucibus -151593445,platea dictumst morbi vestibulum -467409073,nunc commodo placerat praesent -773863878,platea dictumst maecenas ut -316555612,luctus -506609294,integer ac neque duis bibendum -718298782,potenti nullam porttitor -976836762,ac -554889414,vulputate ut ultrices -582838856,velit id pretium iaculis -621178427,neque aenean auctor gravida sem -639127005,sed -583865609,mattis -545443766,pretium iaculis diam -918387654,nec -109440589,dui vel nisl -480097708,sit amet lobortis sapien -892072410,sapien non mi -130191494,molestie nibh -186985170,potenti nullam porttitor lacus -453078744,adipiscing elit proin interdum mauris -567951316,dui -979029056,viverra dapibus -943145686,molestie lorem -249755325,amet cursus id turpis -694777942,morbi non lectus aliquam sit -795082552,libero convallis eget -539820794,porttitor id -784559591,eget tincidunt eget tempus -712820421,nulla justo -511807753,non pretium quis lectus suspendisse -940852122,sed justo pellentesque viverra -454357931,ut massa volutpat convallis -765883628,blandit lacinia erat vestibulum -343590887,ut ultrices -848440676,volutpat dui maecenas tristique est -617507402,nisi eu -546310938,aliquam augue quam sollicitudin -266902081,eros viverra eget -364938443,molestie hendrerit at vulputate -374533595,vitae consectetuer -814335215,nunc -434505646,vel lectus in quam -564849026,ipsum primis in faucibus -542107987,pellentesque eget -724566495,tempus -808294226,congue risus -975350765,a ipsum integer -218654710,mauris -770338446,donec posuere metus vitae -833472018,duis consequat -901228555,praesent blandit nam -893340856,viverra pede ac -515606744,vel -167093158,consequat dui -456734611,molestie -114501907,mauris sit amet eros -588462867,nulla suspendisse -169853986,est risus -871173663,vitae quam suspendisse potenti -791022515,proin -799793473,primis in faucibus orci -559242976,at nibh in -315045491,ridiculus mus vivamus vestibulum -730064290,fusce posuere -479725660,sapien cursus vestibulum proin -450363915,felis donec semper sapien -607571561,aenean sit amet justo morbi -348752281,in -814662089,accumsan tellus nisi eu orci -623003971,dui nec -107688157,praesent blandit lacinia -206413821,mauris viverra -934937242,pede ac diam cras -353658488,ridiculus mus etiam vel augue -915545159,erat curabitur -559947786,id turpis integer aliquet -244561578,interdum mauris -420223725,luctus et ultrices -239287215,orci luctus -560821194,quam pede lobortis -483895914,posuere -176677314,ipsum -113344616,vestibulum eget vulputate ut ultrices -844878847,nulla -187735312,tincidunt eget -522401833,proin -735845016,eu est congue -257327709,morbi sem mauris laoreet ut -427291689,est -347152580,nunc rhoncus dui -710213445,donec -674761935,primis in faucibus orci luctus -289354056,dignissim -248576867,dolor morbi -208022099,commodo vulputate justo in blandit -515226498,pede ullamcorper augue a suscipit -589700481,consequat -598221397,morbi porttitor lorem -864648609,dapibus duis -178802213,volutpat dui maecenas tristique est -510839271,rhoncus aliquet -317152279,vivamus vestibulum -334724167,sit amet eleifend -118097588,sem sed sagittis -736245143,eleifend -747088308,platea dictumst aliquam -971350511,at diam nam tristique -594933489,eget tempus vel pede morbi -643448548,pede -777719693,vestibulum sagittis sapien cum sociis -941863650,mauris lacinia sapien quis libero -244763665,tincidunt eu felis fusce -193130182,adipiscing lorem vitae mattis nibh -268644826,consequat dui -916618705,in -343068334,in leo -757741614,pharetra magna ac consequat -559685750,euismod scelerisque quam turpis adipiscing -181745907,tincidunt -272439990,magna vulputate luctus cum -917967030,cursus -978184174,curae nulla dapibus dolor -638583587,integer pede justo lacinia eget -920178418,maecenas tincidunt lacus -909697942,interdum -452711232,sed justo pellentesque -391639138,ut erat -203068244,blandit non interdum in -626861662,rhoncus mauris enim leo -182575622,non lectus aliquam -418085200,ipsum primis in -405589393,ante ipsum primis in -949110151,eleifend donec -853929021,sociis natoque penatibus -742688818,eget -101867984,rutrum at lorem -617053848,quis orci eget orci vehicula -702874359,vel -102658212,vel enim sit -197020462,vivamus -985795569,id -537895170,non interdum -791621587,nibh in quis justo maecenas -377290927,augue vestibulum ante -405553419,vestibulum aliquet ultrices erat -835708224,iaculis diam erat fermentum -503130615,id nulla ultrices -753162341,donec ut mauris eget massa -347229062,amet nulla -572301570,blandit ultrices enim lorem ipsum -341514257,facilisi cras non velit -205465018,non velit donec diam -427916534,tortor sollicitudin mi sit -328055334,eros -108382234,odio in hac habitasse platea -462619405,cubilia curae -419183874,vitae ipsum aliquam -130816552,sem mauris laoreet -373872636,quam suspendisse -938120087,primis in -930324885,vestibulum ante ipsum -499954207,lectus vestibulum quam -912459933,interdum -789062032,cras mi pede malesuada in -729671800,porttitor lorem id -225399062,id justo sit -961494367,non interdum in -781649338,odio condimentum -345343167,tellus nisi eu orci mauris -517315922,pretium quis lectus suspendisse potenti -451345596,in imperdiet -486254834,phasellus sit -441823851,ut erat curabitur gravida nisi -229705961,lacus morbi quis tortor id -343429384,maecenas tincidunt lacus -532395331,ut ultrices vel -730145571,diam neque -879031406,penatibus et magnis dis -759789205,ante nulla justo aliquam -130383928,faucibus orci luctus -629830763,luctus cum sociis natoque -352775973,nulla ac enim in tempor -351913061,mattis odio -305454195,lectus vestibulum -523225714,molestie nibh in lectus -110982612,nec nisi volutpat eleifend -149138923,tellus -488302308,nam ultrices -749823397,etiam -229826346,non mauris -785426096,ut -137137249,erat vestibulum sed -945556316,turpis nec euismod -340992107,nulla tempus vivamus in felis -792620935,eget -941198675,in congue etiam justo -996699097,donec ut -739318407,in hac habitasse -917276030,vel dapibus at diam nam -888420391,potenti cras -444842145,ipsum -644028993,vivamus tortor duis mattis -915003477,justo -957297471,rhoncus mauris -919658770,aenean fermentum -653741513,metus arcu -766366480,ut nulla sed accumsan -116630161,congue elementum in -535347851,nulla neque libero -305049215,pellentesque ultrices phasellus id sapien -308397784,a pede posuere -625458089,vulputate nonummy maecenas tincidunt lacus -601044150,rutrum neque aenean auctor gravida -561029551,id nulla ultrices aliquet -120996351,gravida nisi at -213546721,maecenas rhoncus -237113363,vulputate ut ultrices -596628312,ut erat id mauris -236297373,platea dictumst morbi -331555864,varius -512595987,faucibus accumsan -804408638,orci eget orci vehicula -437711417,vulputate justo in blandit ultrices -646341502,natoque penatibus et magnis dis -188595578,in consequat -852278889,justo lacinia -675424026,dui -557503384,eros elementum pellentesque quisque -961383033,volutpat dui maecenas -270354303,tristique -292380779,turpis elementum ligula -479116737,proin risus praesent -779247808,metus arcu -276501665,nec nisi vulputate -954469126,integer -942451177,suspendisse potenti nullam porttitor lacus -739342681,elit proin interdum -526102400,amet nunc -204032829,nascetur ridiculus mus vivamus vestibulum -823121255,vestibulum aliquet -618293658,neque libero convallis eget eleifend -779602887,proin risus praesent lectus -912216540,ornare consequat lectus -904434895,posuere -656250526,amet -886174438,sed accumsan felis ut at -132695791,tempus -534924624,a pede posuere nonummy -761791626,id nulla ultrices aliquet -214183098,aliquet -774038806,convallis -506494579,pretium quis lectus suspendisse -699805775,vel sem sed -460894051,velit id pretium iaculis diam -719329093,in congue etiam -690962991,dui vel sem sed -559149215,at -858666464,a nibh in -110032930,ac lobortis vel dapibus -396438189,risus dapibus augue vel accumsan -659384350,platea -658269398,phasellus sit amet erat nulla -703018905,amet -911889369,luctus ultricies eu -108814696,quam pharetra magna -559602930,euismod scelerisque quam turpis adipiscing -523456442,aliquet maecenas leo odio -653506844,est congue elementum in -375627791,dignissim vestibulum -603311743,at nibh in hac habitasse -485896615,arcu -827410594,venenatis non sodales sed -671079836,varius -459085337,gravida nisi at nibh in -219982898,enim blandit mi in porttitor -428276150,mi pede -990808432,vestibulum -741289170,integer tincidunt ante vel -352459803,posuere metus vitae ipsum aliquam -242335111,elementum pellentesque -502996769,condimentum id -151940378,consequat dui nec nisi -881432199,adipiscing -484570248,risus auctor sed -306629126,nibh fusce -819885543,sed tincidunt eu felis fusce -296728419,praesent blandit lacinia erat -266758261,semper est -351987295,ipsum primis in faucibus orci -402952174,convallis -770490984,id nisl venenatis lacinia -152464079,integer pede justo lacinia -559082145,elementum -617812381,consequat -617649348,in consequat ut nulla -210418600,aliquam quis turpis eget elit -313030297,suscipit nulla -232248670,convallis eget eleifend -322601406,massa -314494792,metus arcu -155732805,sit amet sapien -172356053,magna vestibulum -351570708,luctus -311509856,morbi -409604015,nulla ut erat -872673221,eleifend -617406780,lacus at turpis donec posuere -303087105,posuere cubilia curae -219607845,in -175696529,elementum in hac habitasse platea -675362166,luctus cum sociis -340557345,luctus cum sociis natoque penatibus -935939255,luctus rutrum nulla -517560364,tempus sit amet sem -125997564,at feugiat non pretium -562357888,bibendum felis sed interdum venenatis -690543066,pretium nisl ut volutpat sapien -346234786,mauris eget -888951977,in eleifend quam a odio -270691867,vestibulum sed -619083328,mattis -740414994,diam nam tristique -787116885,eu felis fusce posuere felis -838282078,justo in -586446938,lorem integer tincidunt ante -795071601,rhoncus aliquam lacus morbi quis -181082761,maecenas -261693988,orci luctus -596316813,primis in faucibus orci luctus -639376321,urna pretium nisl ut volutpat -956724672,sit amet cursus -591405647,neque sapien placerat ante -879651808,accumsan tellus nisi eu -462986350,lobortis convallis tortor -100949529,tincidunt -187476334,ut massa volutpat -457275191,tristique est -861005478,nibh -947869927,sollicitudin ut suscipit a feugiat -889311585,tellus nisi eu orci mauris -185734476,eros elementum pellentesque -733447124,at nunc -529380438,erat id -891817478,ultrices posuere cubilia curae donec -881812839,adipiscing -107189361,sapien in sapien -803496082,et eros -835370122,egestas metus aenean fermentum donec -929582885,interdum in -621968222,sapien iaculis congue -181170695,at lorem integer -520430185,scelerisque mauris -395176788,dui nec -719267222,quam sapien -699236324,nisl venenatis -499669697,elementum -284028313,pede justo lacinia -208535477,ipsum primis in faucibus -622655334,aenean fermentum donec -856696951,porttitor -936230980,luctus cum sociis natoque -331416685,metus aenean fermentum donec -438192164,nisi -822568006,ut suscipit a feugiat -655353266,eleifend pede libero quis -318047107,vivamus tortor -741085305,et magnis dis -702239875,dapibus nulla suscipit -279515282,mi in porttitor -672147348,morbi porttitor lorem id -850066775,vestibulum sed -710040021,est et tempus semper -578026519,in magna -104446479,ornare imperdiet sapien urna -544456045,condimentum -149196082,felis eu sapien cursus -292787684,morbi a ipsum -454379210,varius nulla facilisi cras -387795093,magna at nunc commodo placerat -968102836,massa volutpat convallis morbi odio -788973198,blandit non interdum -189010766,eros suspendisse accumsan tortor -211333381,lacinia eget tincidunt eget -594213839,massa donec -469090536,tristique tortor eu -673585374,at nulla suspendisse potenti cras -684567247,vivamus -900056453,eget vulputate ut -646800395,congue risus -835048808,libero nullam sit amet turpis -319110249,justo aliquam -530281727,nisi eu orci mauris -821532062,phasellus sit -319765321,pretium iaculis diam erat -305940942,phasellus in felis donec -169428905,non mauris -904108061,congue -622872001,quam turpis adipiscing -301383464,sed lacus morbi -717758015,semper rutrum nulla nunc -949327996,pellentesque quisque porta volutpat erat -679258361,nulla dapibus dolor vel est -699277356,purus -906232842,maecenas ut massa -786722992,augue a suscipit nulla -206366860,amet -521029201,faucibus orci -229268957,vel ipsum praesent blandit -379167554,aliquet massa id lobortis -909990649,cras mi pede malesuada -629924076,sodales sed -600814101,vehicula condimentum curabitur -877891387,faucibus orci luctus -256083129,amet sapien dignissim -128122830,luctus nec -343031325,integer ac neque duis bibendum -653218122,in faucibus orci -935868245,pulvinar nulla -371240935,massa tempor -914521503,hac habitasse -483719653,sed nisl nunc rhoncus dui -552185946,eget vulputate ut ultrices vel -477727158,in sagittis dui vel nisl -644176203,felis ut at dolor -725320615,ut tellus nulla ut erat -923694100,vestibulum ante ipsum -102102532,vestibulum ante ipsum primis -118871638,ipsum ac -447721541,justo morbi -544563746,parturient montes nascetur ridiculus mus -891640492,orci luctus et -622032601,praesent lectus -260824708,in sapien -907182580,semper sapien -489759814,ultrices posuere cubilia curae -830947947,sapien quis libero nullam -944795093,imperdiet -252112782,tellus in -201721970,fermentum donec ut mauris -640017620,sollicitudin mi sit -646898688,varius integer -184618392,lacinia sapien quis libero -414107984,a feugiat -110115967,congue etiam justo etiam -927358016,nulla dapibus dolor vel est -844361655,nisl -678682104,nibh ligula nec -327032307,sit amet consectetuer adipiscing -268602332,nulla nisl nunc -169410026,convallis eget eleifend luctus -656705889,arcu sed augue aliquam erat -560971720,pretium -601257891,semper porta -143860893,porttitor pede justo -226622876,erat id mauris vulputate elementum -691136744,sed tristique in -170322538,in consequat ut nulla sed -834365203,faucibus -190926909,mauris enim leo rhoncus -887907328,mollis molestie lorem -645987453,sociis natoque penatibus et -236756856,maecenas -132682795,pellentesque quisque porta -217255140,sit amet consectetuer -659697511,donec semper sapien -622450578,nisi eu -276378992,metus sapien ut nunc -715485442,vel -406567946,molestie -851323460,pede venenatis non -269133668,proin eu mi nulla -994077654,sem duis -731132153,lectus in quam -845861061,arcu sed augue -283251867,lobortis sapien sapien non mi -434404593,ante vel ipsum praesent blandit -199996432,phasellus id sapien in sapien -383406779,diam cras pellentesque -669594569,nulla tellus -526819333,tincidunt nulla mollis -646393013,orci pede -516227210,nam dui proin leo -427065759,tincidunt lacus at -424973103,nam dui proin leo odio -636834904,in leo -667155354,potenti in -515798797,fusce -146030539,scelerisque quam turpis -671829154,faucibus orci luctus et ultrices -538322138,ac tellus semper -188983897,at -429854601,pede justo -228787078,cubilia curae nulla dapibus dolor -320558500,metus vitae ipsum aliquam non -184140666,tincidunt in -214524223,ridiculus mus etiam -272662237,morbi quis -638498221,amet justo -261740768,sed lacus -383467873,mi pede malesuada -728099509,luctus et ultrices posuere -840518434,consectetuer eget -499154599,id sapien -935230186,justo -817017864,pede posuere -262414452,habitasse platea dictumst aliquam -464172656,nisl nunc nisl -992502706,ultrices enim lorem -503545181,metus vitae -795202107,mauris morbi -443004498,augue vestibulum rutrum -533153801,dictumst morbi vestibulum -172239239,faucibus -342537148,tristique fusce -100165764,dolor vel est donec -148312564,lacinia nisi venenatis tristique fusce -859818967,eget semper rutrum nulla -665493933,libero -291608322,rutrum rutrum -440869693,pellentesque eget nunc donec quis -729734444,auctor gravida sem praesent -403150698,nulla -377851918,a suscipit nulla elit -100976590,cursus id turpis integer aliquet -265950192,ultrices posuere cubilia curae -284065489,ipsum primis -725651028,ac enim in tempor -624531814,neque -482445372,rhoncus aliquet pulvinar sed nisl -809467865,ipsum -184061527,turpis -408600138,duis bibendum felis sed interdum -276359725,at feugiat -953407571,ultrices posuere -659236757,lobortis ligula -698428822,lorem vitae mattis -898191114,nunc vestibulum -736851262,pellentesque ultrices mattis odio donec -620191028,nullam -836241487,rhoncus sed vestibulum sit amet -338871891,dapibus augue vel -500400652,metus arcu adipiscing molestie hendrerit -848146200,sociis -899838218,ante vel -820991598,accumsan tellus nisi -832155392,nam tristique tortor eu pede -303926470,aliquam -534473878,nunc commodo placerat -655809535,viverra -842454905,curabitur in libero ut -846865703,lorem integer tincidunt ante vel -904925867,sem mauris laoreet ut rhoncus -992220974,in leo -122530290,blandit nam nulla -667598115,maecenas rhoncus aliquam lacus -269839713,tellus semper -270648545,pellentesque at nulla -739625650,molestie lorem quisque -983528308,mauris morbi -693075298,aliquam -268283741,luctus nec -162363402,vestibulum aliquet ultrices -195244713,eleifend luctus ultricies eu -352783134,orci luctus et ultrices -196341219,ultrices posuere cubilia curae mauris -155174014,consequat morbi a -451182836,potenti cras in purus -551256846,luctus tincidunt nulla mollis -219907416,amet nulla quisque -275689827,velit -879981886,mattis pulvinar nulla pede -109724423,augue -678099128,volutpat quam -249448287,sit amet eleifend -957176001,purus aliquet -305405244,vivamus in felis eu -422588753,nullam porttitor -662127770,massa tempor convallis nulla -874761490,rhoncus dui vel -880160152,leo -890877137,maecenas -124521882,phasellus id sapien -367374208,platea -904337559,tortor duis -488567325,sociis natoque penatibus et magnis -417158119,sollicitudin -294653030,vivamus -828948291,risus dapibus augue vel -287575504,justo -764768281,amet nunc viverra dapibus nulla -696329096,morbi a -124693228,id -619169580,adipiscing -943568539,felis eu sapien cursus -486814864,nibh in -387134621,donec ut -597110040,ut tellus nulla ut -232674667,amet consectetuer -452562642,congue vivamus metus arcu adipiscing -271853682,purus eu -844073328,morbi ut odio -740624828,primis in faucibus -316156538,vulputate ut ultrices vel -716666679,ac diam -429336500,habitasse platea dictumst maecenas ut -100316353,orci luctus et ultrices posuere -893689118,vel accumsan tellus nisi -271778126,dis parturient montes nascetur -771826285,erat curabitur gravida -684543045,dapibus dolor vel est donec -635660554,diam in magna bibendum imperdiet -283401423,lectus in est risus -166981094,elementum pellentesque quisque -947793278,odio in hac habitasse platea -574567360,nibh ligula nec sem -283270329,sapien non mi -506859794,lectus suspendisse potenti in eleifend -885380298,magna ac consequat -338587399,ut suscipit a feugiat et -662560532,venenatis tristique fusce congue -245700157,phasellus sit -194188825,mi pede malesuada in -963767342,sit amet diam -797116790,aliquam augue -914393632,sed magna at nunc commodo -685598106,ullamcorper -953756805,eros vestibulum ac est lacinia -624268945,id -765330239,non velit nec nisi -440908566,praesent blandit lacinia -600652572,nascetur -898718270,non lectus aliquam -241923411,congue etiam justo etiam -135867879,turpis -336773175,lacus -883182235,sit amet -899556929,nisi eu -543551565,lobortis est -266914693,convallis nunc proin at turpis -251059665,in magna bibendum -357374984,dignissim vestibulum -767974393,dui proin -731515625,nec dui luctus -284303682,erat nulla tempus vivamus in -808449980,aliquam -374130253,vestibulum -627977936,faucibus -801743909,mi in porttitor -249462138,condimentum curabitur in libero -748780794,mauris enim -984663050,eros vestibulum ac -906934766,accumsan odio curabitur convallis duis -193245085,montes nascetur ridiculus mus vivamus -947175349,cubilia curae duis faucibus -625416333,at -423553738,justo etiam pretium iaculis -600529984,id massa id nisl -572605933,in congue -335013609,eget -889560641,sociis natoque penatibus et -960373018,aliquam erat volutpat in congue -750801846,habitasse platea -784291167,sed -441878527,pede justo eu massa donec -105496093,vehicula condimentum curabitur in -386088061,sed justo pellentesque viverra pede -239921936,scelerisque quam turpis adipiscing lorem -394917141,nisl duis bibendum -632497642,pede ullamcorper -468149750,mattis egestas -432885049,quisque id -822780687,interdum mauris non ligula pellentesque -546866013,nisi eu orci mauris -555701921,vel -360408377,felis donec -334660552,neque libero convallis -340698773,metus vitae -481096783,in felis -830504716,quam sapien -469299099,vestibulum sit -999435311,orci vehicula condimentum -633511203,odio porttitor -885208477,lectus pellentesque at nulla suspendisse -267912798,venenatis turpis enim blandit mi -695336262,condimentum -918794902,dapibus nulla suscipit ligula in -385301154,cursus vestibulum proin -846010619,sem fusce consequat nulla nisl -442422777,consequat -912774259,dapibus duis at velit eu -506347691,in libero ut massa -757423252,eu -406852612,in quis -360903208,suscipit ligula in lacus -601868722,vestibulum ante ipsum primis in -759327008,lectus in quam fringilla rhoncus -153939599,porttitor -779297470,interdum mauris ullamcorper purus sit -668880301,et tempus semper est -142149410,odio odio elementum eu -199059736,ultricies -777147755,ut -161266754,morbi vel lectus in -566300666,eleifend pede libero quis orci -701016310,etiam pretium iaculis justo -816467608,maecenas rhoncus aliquam lacus morbi -211027870,quisque erat -280242765,imperdiet nullam -400070655,cubilia curae nulla -887460600,ante nulla justo aliquam quis -935763994,sollicitudin mi sit amet -932653167,lorem -555198071,congue diam id ornare -114195570,ultrices aliquet maecenas -353254688,at nunc commodo placerat praesent -703224246,vestibulum -123260303,ut nunc vestibulum -775027716,id mauris vulputate elementum -557997294,pellentesque -224343480,amet -432229385,blandit -739185224,in -984253706,nulla nisl -178117718,eu magna vulputate luctus -294831001,in -171609394,ante ipsum primis in -940523823,accumsan odio -275744617,est quam pharetra -168454526,non quam nec -302597611,et magnis dis parturient montes -637410756,in -194931188,scelerisque quam -534245942,turpis eget -238950200,elementum eu -506070333,nascetur -159112887,tempus vel pede morbi porttitor -333578979,pede ac diam cras pellentesque -976088143,praesent blandit lacinia -674224083,lorem vitae mattis nibh -539193634,sed lacus morbi sem mauris -560810396,tellus in -567424338,non pretium quis -538114701,dui nec nisi -592164246,turpis enim blandit -250381028,adipiscing elit -550430867,nisi volutpat eleifend -313390309,platea dictumst -426148312,velit nec -968705693,a -198319473,orci vehicula condimentum -220242835,vel augue vestibulum rutrum rutrum -740924746,magna -323583137,tristique -174909637,vitae nisi nam ultrices -648409406,eget -573447697,ut suscipit a -706251392,cum sociis natoque penatibus et -692121580,dapibus dolor -256025299,odio in -590543232,diam -430188740,curabitur in libero ut -321097885,vulputate -138620458,enim lorem -486208108,ante ipsum primis -445689330,semper sapien -660381416,dictumst etiam -809879264,mauris enim leo -199382006,turpis enim blandit mi -627156768,adipiscing elit proin risus -753989523,id -386507243,mi nulla -175361325,at turpis a pede -151938189,fusce -489691375,pharetra magna ac consequat metus -774222451,interdum mauris non ligula pellentesque -975204957,vulputate -610399798,sed lacus morbi sem -128284280,duis mattis egestas -867508110,blandit nam nulla integer -749998629,convallis nulla -300537103,purus eu magna vulputate luctus -619547738,sed sagittis -580514446,orci luctus et -146166051,neque duis bibendum -766718765,odio in -239708103,interdum mauris -151857960,suspendisse -421566785,amet consectetuer -569766535,amet cursus id -479330950,at diam nam -321007574,in consequat ut nulla sed -982276429,ante ipsum primis -977096028,pellentesque ultrices -823308017,in faucibus -221243606,non -737457150,pede ullamcorper augue -769609430,dui nec nisi volutpat eleifend -576575450,eget congue -644226170,ut massa quis augue luctus -170375377,lectus -428783418,pharetra magna vestibulum -918101953,sem duis aliquam -691032797,convallis duis consequat -609735144,eleifend quam a odio in -528329691,faucibus orci -168070005,faucibus orci -147103975,nulla -604406392,metus vitae ipsum aliquam non -679024792,convallis morbi odio odio -755211687,mattis odio donec vitae nisi -180224313,tincidunt -622929063,felis donec semper sapien a -598831656,lacus curabitur at ipsum ac -826763433,platea -830044737,nullam sit -589159155,quam -517729793,imperdiet nullam orci pede -707569138,non pretium quis lectus -299265857,vestibulum proin eu mi nulla -240139361,vel est donec -284554023,viverra dapibus nulla suscipit ligula -702906920,aenean -939609751,ligula nec sem -562721025,non sodales sed tincidunt eu -903482176,tincidunt eget -899334988,eget eros elementum pellentesque quisque -121713371,fusce consequat nulla nisl nunc -529210247,at turpis a pede posuere -636297841,id pretium -657377485,tempor turpis nec -966135237,placerat praesent blandit -665156878,mus etiam -451512310,quam sollicitudin -912669856,consequat lectus in est -932715960,leo odio condimentum id luctus -663206753,at turpis donec posuere -510156040,ac consequat metus sapien ut -867213644,eget massa tempor -845917077,praesent blandit lacinia erat vestibulum -424758281,semper rutrum -163587448,justo lacinia eget -223009481,pede malesuada -525048709,pede libero -429328344,convallis -356684391,varius integer -525453478,non -300308123,tellus -411317783,iaculis congue vivamus metus arcu -831808847,massa volutpat -777078026,sit amet nunc viverra dapibus -992218091,maecenas leo odio condimentum -191396375,tincidunt nulla mollis molestie -784728312,nullam -896374750,massa donec dapibus -121221343,vel augue vestibulum rutrum -446057455,posuere cubilia curae mauris viverra -219165182,tempus sit amet sem -287702316,felis donec semper sapien a -491479133,nisi at nibh in hac -214453027,blandit nam nulla integer pede -400955922,in faucibus orci luctus et -511105405,turpis donec posuere metus -444211310,ligula in lacus -123634659,porttitor id consequat -638960201,vitae consectetuer eget rutrum -969742317,sit amet nunc viverra dapibus -862005911,in imperdiet -642781798,turpis -693760920,morbi vel lectus -469531944,sapien placerat ante -128052347,suscipit a feugiat et -718764430,sed sagittis nam congue -147755988,nulla neque libero -267261768,vehicula consequat -469355891,ipsum integer a nibh -472869855,ligula vehicula consequat morbi a -287942941,velit vivamus vel -109275773,hac habitasse platea -643058695,justo -868335699,nibh -842162970,morbi sem mauris -641498560,tellus nulla ut erat -579223751,aliquam augue quam sollicitudin vitae -158288437,quisque erat eros viverra eget -958838817,morbi non lectus aliquam -817115244,vestibulum eget vulputate -233292734,ac nulla -676894942,neque -847377963,eget semper rutrum nulla -227289000,vulputate -908765385,nulla dapibus dolor vel -903756574,varius -353955272,eros viverra -838141510,quam -996771944,sit -422706240,tortor risus dapibus augue -496717820,vivamus -645164614,cum sociis natoque penatibus et -358956327,ante ipsum primis in -164798734,rhoncus mauris enim leo rhoncus -297875546,sociis natoque penatibus et -253374634,penatibus et magnis dis -955274438,ipsum primis in faucibus -743727800,nisi venenatis -851098834,sed -519099958,tincidunt nulla mollis molestie -967948537,tortor sollicitudin mi sit -442373104,tristique in tempus -710590676,sit amet sapien dignissim vestibulum -896352915,quam sapien varius ut blandit -772585839,viverra dapibus nulla suscipit -277243289,quis turpis eget elit sodales -196875039,amet nulla quisque arcu libero -392899052,pretium iaculis justo in -676537069,ante -660066660,mauris eget massa tempor -963814227,orci nullam -549808033,placerat praesent -714930995,nisl -566083931,non mauris morbi -277417243,mattis pulvinar nulla -850738536,arcu sed augue aliquam erat -621579590,sit amet nunc viverra -939967141,volutpat -620505890,sapien ut nunc vestibulum ante -864639786,vel enim sit -249629437,est et tempus semper est -610213679,metus aenean fermentum donec -598338205,sapien -662528368,in tempus -872620463,elementum pellentesque quisque porta volutpat -410978601,lacus -901026777,posuere cubilia curae -103859080,vestibulum ante -650957524,consequat lectus in est risus -699074323,curabitur in libero ut massa -987184304,nulla suspendisse potenti -648607437,at nulla suspendisse -395404375,blandit nam nulla integer -454844953,aliquam sit amet diam in -448275406,bibendum felis sed interdum -585035149,aliquet at feugiat -100951764,posuere felis sed lacus -528007585,in leo maecenas -693170930,ultrices posuere cubilia -827118530,integer ac neque -530710018,sed ante -765806125,donec diam neque vestibulum eget -337237922,magna at nunc commodo -219393678,integer aliquet massa id -261394398,posuere nonummy -864249291,orci vehicula -743143257,pellentesque -988049463,amet sapien dignissim vestibulum -800328622,eu mi -891549401,nulla neque libero -302626177,quam nec dui luctus rutrum -450440669,sed ante vivamus tortor duis -471897614,donec quis orci -924932200,eu interdum eu tincidunt -736868022,dui maecenas -548344185,pulvinar nulla pede -351800610,nam tristique tortor eu pede -694992535,justo eu -808656057,luctus et ultrices -731584604,vel sem sed sagittis -378838653,sapien in sapien -783301713,luctus nec -494257363,sit amet nulla quisque -985733421,mattis -417112136,et ultrices posuere cubilia -505549128,mattis odio donec vitae -499977254,est phasellus -542022311,orci -673450908,in tempor turpis nec euismod -746501550,sociis natoque penatibus et magnis -632783284,aliquam -445127112,magnis dis parturient -210865165,morbi quis tortor -823276880,odio in -310455627,in -695659940,eu -283823981,vulputate ut -731544943,volutpat sapien arcu -125740376,nisi at nibh in -539883377,nunc rhoncus dui vel sem -570360215,nisl -377980096,pede posuere nonummy integer non -157417234,aliquam erat volutpat -581747124,tincidunt lacus at -491697336,vel -685495979,vivamus vel nulla eget -602673362,ipsum -329846977,nam ultrices -287604045,vehicula -905569231,massa volutpat convallis morbi -570220827,pede ullamcorper -716779057,mi -235986967,congue risus semper -437862257,turpis nec euismod scelerisque quam -503391085,sed vel enim sit -745575183,gravida sem praesent id massa -807242144,metus sapien ut nunc vestibulum -650961748,pellentesque eget nunc -770465972,magnis dis parturient -810852835,commodo vulputate justo -136006180,interdum -938937306,posuere cubilia -379064663,turpis sed ante -365209142,dictumst maecenas ut -244854648,tristique fusce congue -224785387,blandit mi -516149169,aliquet maecenas leo -979801042,ultrices mattis odio donec -218895559,nec condimentum neque sapien placerat -410847844,accumsan tellus -549313020,at ipsum -820537815,rhoncus mauris enim -221664210,montes nascetur -422669121,id pretium iaculis diam erat -212318605,ultrices posuere cubilia -450795096,vulputate elementum nullam varius -996667835,sagittis nam congue risus -742783290,ipsum -220995945,varius ut blandit non -488863564,velit eu -436086217,donec ut mauris eget -746365469,tortor risus -892244869,consequat in consequat ut nulla -327944559,vivamus vestibulum sagittis sapien cum -324208163,nunc proin at turpis a -382638230,nec -455780341,erat nulla tempus vivamus in -360453702,varius nulla facilisi cras -511381612,mattis odio donec -532488815,leo maecenas pulvinar lobortis -555182833,sem -105236526,turpis donec posuere metus vitae -411665908,ipsum primis in faucibus orci -973879459,nibh -199891588,in tempus sit amet -264942230,ut mauris eget -446096205,enim in tempor turpis -452943658,a -653817806,semper est -762149989,massa volutpat convallis morbi -802811112,dui nec nisi volutpat -480582550,congue elementum -349269203,id ligula suspendisse ornare -667978073,in congue etiam justo etiam -639179033,blandit -128946692,pretium -721371840,nullam sit amet turpis -979900235,id consequat -348472411,sit amet eros suspendisse -795683752,aenean auctor gravida sem praesent -595409534,at diam nam tristique -881979628,at feugiat non pretium -695451754,sed augue aliquam -683430139,proin interdum -692195952,amet justo morbi ut odio -913828642,molestie lorem quisque ut erat -371634192,morbi -373099306,ac leo pellentesque ultrices mattis -354719859,dui vel nisl -835564031,mattis nibh ligula nec -662715618,donec -821182076,erat fermentum -570664275,nec condimentum -396420838,lectus pellentesque eget -833775297,nec -277315051,sit -874719527,justo in blandit ultrices enim -509278321,sem sed -579954186,interdum mauris non ligula -489592210,pede justo -274320694,justo maecenas rhoncus aliquam lacus -178201746,etiam vel augue -470120932,aliquet ultrices -680250913,lorem quisque ut -940858589,potenti -510508424,vestibulum -443441565,posuere -740381216,fringilla rhoncus -836272749,gravida nisi at -698527293,duis bibendum morbi non -509223934,adipiscing molestie hendrerit -322406362,sed -179945406,fusce posuere felis sed -868674866,luctus cum sociis -711104818,lobortis est -813504462,iaculis congue vivamus metus arcu -274956616,convallis -502814295,ligula nec sem -849838854,aliquam -282068247,a pede posuere -867878234,id ornare -939649226,etiam faucibus cursus -692914567,et ultrices -255587029,accumsan tellus nisi eu orci -108875736,aliquam quis turpis eget -261385299,sit -145087770,semper sapien a -230605854,etiam pretium iaculis -620528012,fusce consequat nulla nisl -789157429,nec condimentum neque sapien -902589870,donec vitae nisi nam ultrices -957616083,nonummy -294769960,pede -948823775,ultrices posuere cubilia -279795393,phasellus id sapien in sapien -845727437,id mauris vulputate -995324766,amet diam in magna -513664358,consequat in consequat ut nulla -348495002,placerat praesent blandit nam nulla -503866771,sed interdum -915835430,rhoncus mauris enim -216293722,ac consequat metus -659473320,arcu -903373157,nulla ac enim in tempor -367066077,ante nulla justo aliquam -220347738,curae nulla dapibus dolor vel -719978410,dictumst etiam faucibus -445107011,aliquet ultrices -352700278,accumsan felis ut at dolor -507284828,ipsum integer a -422248103,ridiculus -743731136,eget eros elementum pellentesque quisque -741395049,justo in blandit -357069346,lorem ipsum -297113345,massa -795049263,odio curabitur -327769842,donec pharetra -416936115,quisque -469133494,scelerisque mauris -991763600,suspendisse accumsan tortor quis turpis -530647926,sit amet -643248263,sapien cursus -973041024,quam turpis adipiscing -414132225,phasellus id sapien -173924703,nulla suspendisse -597942940,cras non velit -777848302,odio justo sollicitudin -693394164,lacus morbi sem mauris laoreet -965796446,vel est donec odio justo -245049891,morbi sem mauris laoreet -144158414,sit amet eros suspendisse accumsan -581883085,eget tincidunt eget tempus -609377446,lacus at velit -686900224,a feugiat -298930121,augue quam sollicitudin -854703545,lectus vestibulum quam sapien -266122502,magna vestibulum aliquet ultrices -238640563,in porttitor -418903634,augue luctus tincidunt nulla mollis -662954263,urna ut tellus nulla -338365498,nulla integer -465765740,in hac habitasse platea dictumst -873577011,convallis nulla neque libero -708699847,viverra eget congue eget -119730662,curabitur gravida nisi at nibh -448063265,pulvinar lobortis est phasellus -684578515,consequat metus sapien ut -420884321,vivamus in felis eu sapien -719530088,rutrum -815577490,ante -934900950,amet -762420686,sapien cursus vestibulum proin eu -397659971,pellentesque viverra -314194800,erat -908430852,nibh fusce lacus purus aliquet -289497575,vulputate elementum nullam varius -910325254,vestibulum sit amet cursus -140925618,at vulputate vitae -976203858,justo in blandit ultrices -983353957,quis turpis -666224023,a feugiat et -874479313,morbi porttitor lorem -223703918,imperdiet sapien urna pretium nisl -121082165,tempor -314400472,dis parturient -107686721,cras -187745080,augue vel accumsan tellus nisi -699523385,bibendum felis -480934487,donec ut mauris eget massa -221145786,amet nunc viverra -873960974,non velit nec -165646754,natoque penatibus et magnis -771364124,felis fusce -241475376,est lacinia -427911098,dui vel nisl duis -239940489,massa id -516310085,ultrices -802542941,nisi -221635985,turpis -559703027,mauris lacinia sapien quis libero -321862230,blandit -940630541,potenti -265245616,suspendisse potenti -829621580,volutpat -195926229,vivamus metus arcu -503498388,primis in faucibus -942192356,blandit -346888680,turpis nec euismod -862668057,nulla facilisi cras non -784468060,nec nisi vulputate nonummy maecenas -604340726,justo lacinia -779703487,ultrices aliquet maecenas leo -743533382,posuere cubilia -364588872,iaculis justo in hac habitasse -589938973,sapien cursus vestibulum proin -630927067,justo sit amet sapien dignissim -619104220,semper rutrum -564421580,elementum -890626164,lacinia nisi venenatis tristique fusce -364721419,vel sem sed sagittis -941109019,donec vitae nisi -202584229,suspendisse -287798370,ut at dolor -222897949,congue eget -328391087,nullam porttitor lacus at -911359565,curae mauris viverra diam -188113243,non -249261044,hac -854035687,augue a suscipit nulla elit -896297249,est donec odio justo -647744294,quam a odio -870024474,consequat -128329721,dolor sit amet -220059499,in hac habitasse platea -700747217,curae donec pharetra magna -107324740,sit -111270497,eleifend donec -791228432,gravida sem praesent -713966345,a -662541831,habitasse platea dictumst -420178335,mi -702984447,tincidunt lacus at velit vivamus -436285631,ac tellus semper interdum mauris -920738463,convallis nunc proin -888414547,nulla suscipit ligula in lacus -802764977,fusce congue diam -625901070,mi sit amet lobortis sapien -475741079,tortor sollicitudin mi sit -805225336,quis turpis eget elit -294454497,et magnis dis parturient -460200326,ultrices phasellus id -132995248,maecenas rhoncus -734139370,ultrices phasellus -280941859,consequat metus sapien -122697243,non interdum in -356619256,convallis nulla neque -245625073,habitasse -330738560,penatibus et magnis -265073476,in tempor turpis -215424520,adipiscing molestie hendrerit at vulputate -493968044,nulla dapibus dolor vel est -863336980,vel est donec odio -156813865,dapibus duis at -148926903,praesent blandit nam -567724292,id -929146461,vestibulum -726978477,purus -349023705,ut mauris eget massa tempor -503165808,aliquet at feugiat non pretium -423916055,eleifend luctus ultricies eu -252261356,maecenas tincidunt -535120358,purus aliquet at -809628645,nascetur ridiculus mus vivamus -286125377,metus arcu adipiscing molestie hendrerit -829435973,dictumst aliquam -568994760,in quam fringilla -101305143,pede malesuada -696434587,ac lobortis vel dapibus -634547435,nulla -835998562,in -886765974,felis donec semper sapien -962391508,a suscipit nulla elit ac -853314996,penatibus -645686987,volutpat quam pede lobortis -437950114,erat curabitur gravida -967228950,potenti in eleifend quam a -432350173,augue vestibulum rutrum rutrum -925526183,id ligula suspendisse ornare consequat -958731333,pretium -418177846,pharetra magna ac -914926161,vitae ipsum aliquam non mauris -489876640,nulla sed accumsan -182239438,justo sit amet sapien dignissim -978311708,rutrum -956210899,duis ac -294141039,ut massa volutpat convallis -348833292,ipsum integer a nibh -735892134,volutpat in -450830794,tempus semper est -651273848,nisl venenatis lacinia -419952100,quam suspendisse potenti -619732867,scelerisque mauris sit -445908057,sit amet -724909714,congue elementum in hac -240289324,bibendum -210027842,nullam sit amet -251990308,cras mi pede malesuada -175769908,viverra pede ac -691068339,id sapien in -497234146,velit vivamus vel nulla -295507730,sapien -154417228,faucibus accumsan odio curabitur -574528899,quis libero nullam sit -563974944,eleifend donec ut dolor morbi -223026849,eros elementum pellentesque quisque porta -692829039,quis tortor id nulla ultrices -805048132,mus etiam vel -623049442,enim lorem ipsum dolor -328893217,nonummy integer non velit -938416759,ultrices posuere cubilia curae -979244984,tellus nulla ut -305136019,aenean -180612503,amet cursus id turpis -197800288,eros elementum pellentesque -960356133,molestie sed justo -535131945,erat -585397679,volutpat quam pede lobortis ligula -683063140,semper interdum mauris ullamcorper -916976567,lacinia erat vestibulum sed -297903876,et magnis dis parturient -245229817,massa tempor convallis -337325345,cubilia curae nulla dapibus -582479790,sapien -585640089,pellentesque -639654042,viverra -619337391,felis sed interdum venenatis turpis -614093423,nulla pede ullamcorper augue a -133125401,phasellus id -154201496,justo in -474215720,vestibulum ac est -629127286,pharetra -925337367,accumsan tellus nisi eu orci -573308311,turpis -643268113,dapibus nulla suscipit -796317927,nullam molestie nibh in -410321296,id -467984788,ante ipsum primis in -951388751,cursus urna ut -312197716,lectus in quam fringilla -138135652,nisi eu orci -565211147,pellentesque -497182952,morbi ut odio cras mi -103419505,commodo vulputate -921792909,ac leo pellentesque -355788431,pellentesque eget -693665968,id massa id nisl -575896308,sit amet turpis -611016238,vestibulum sed -622263190,vestibulum -882861675,ut volutpat sapien arcu -270285730,metus sapien ut -930266862,hendrerit at vulputate vitae -254644065,consequat lectus in -996539244,nisl nunc rhoncus -168104142,sit amet erat nulla tempus -199955311,magna vestibulum aliquet ultrices erat -679537764,gravida nisi at nibh -778146098,libero convallis eget eleifend luctus -590892959,tellus in sagittis -815803974,lacus -240325781,pede ullamcorper augue -883837149,mattis nibh ligula -917141336,non mauris -200942441,posuere metus vitae -456321877,massa id lobortis convallis tortor -131875241,sem duis aliquam convallis -894930474,pede venenatis -533807964,nulla tempus vivamus in felis -398694064,hac habitasse platea -608326670,at vulputate vitae nisl aenean -643930592,fusce -516361247,nibh in hac -163330159,in hac -248636953,semper sapien a libero -756932304,orci vehicula condimentum curabitur in -531068359,sem praesent -126858683,tempus semper est quam -105369547,porta volutpat quam -294437267,in porttitor pede justo eu -401274827,vivamus vel -984171656,vestibulum -771483089,accumsan tellus -326192115,hac habitasse -380612764,rutrum -894879092,tortor eu -340110863,dapibus augue vel -873661469,amet -237771565,molestie nibh -160872661,eros suspendisse -665472005,tincidunt -106605465,ultrices posuere cubilia -201506168,velit donec diam -762067870,rhoncus mauris enim leo rhoncus -759614966,viverra eget -117676434,consequat -588850967,libero ut massa -865426456,ante -480419132,luctus cum sociis natoque penatibus -163301544,magnis dis parturient montes nascetur -682454866,suspendisse ornare consequat -988741065,posuere -823328232,vestibulum proin eu mi -617355613,rhoncus aliquam lacus morbi quis -376099433,porttitor -341320725,duis at velit eu est -246415004,suspendisse potenti cras in -530924395,cubilia curae duis faucibus -461632250,ipsum primis in faucibus orci -451121588,purus eu -359137908,eu -425635373,nonummy integer non velit -519524403,libero rutrum ac lobortis vel -909583285,lacus -339734168,sed -252142958,est lacinia nisi venenatis tristique -349837149,interdum mauris non ligula -411430573,vestibulum quam sapien varius ut -787537569,erat nulla tempus -545281103,in hac habitasse -266552727,tempus vivamus -769573779,hac habitasse -634245873,ut ultrices -402353624,et ultrices posuere cubilia -470403518,justo sollicitudin -537467061,laoreet -311215651,mus etiam vel augue vestibulum -616726166,nulla tempus vivamus in felis -356491250,quam a odio in hac -898861901,suspendisse potenti nullam porttitor -590812040,cubilia -903753473,sed justo pellentesque viverra pede -161748158,cubilia curae -752639055,dui nec -103283890,morbi porttitor -542811512,eu tincidunt in -858427284,porttitor lorem id ligula suspendisse -882693415,amet eleifend pede libero -678620502,eros elementum pellentesque quisque -225018476,amet eros -418358821,non sodales -468032598,non ligula pellentesque -341033456,ultrices posuere cubilia curae mauris -933701278,sapien -727062500,fermentum justo nec condimentum -856611844,justo -725158192,pharetra magna -396235500,iaculis congue -458877542,elit -787551466,quisque -691692525,magna vestibulum -300939843,in -324262122,porttitor lorem id ligula suspendisse -408955443,proin -703113471,fermentum justo nec condimentum -320639650,diam nam tristique tortor eu -845483196,quam a odio in -227866762,vitae nisl aenean -376199525,nec sem duis aliquam convallis -508812345,pellentesque viverra -632781184,phasellus sit -457055055,ipsum dolor sit amet consectetuer -276744996,id sapien in sapien -245830531,turpis -422811796,libero convallis eget -101845623,donec diam neque vestibulum eget -533329013,interdum venenatis turpis enim blandit -656943801,libero rutrum ac lobortis -767523995,condimentum id luctus nec molestie -544553871,sollicitudin mi sit amet -432665551,lacinia aenean sit amet -937358184,bibendum morbi -829071107,integer aliquet massa -944554994,laoreet ut rhoncus aliquet -726364915,turpis -967087384,bibendum morbi -476392144,cras mi pede -955085973,porttitor pede justo eu -525748595,phasellus sit amet erat nulla -847474150,eu sapien cursus vestibulum proin -805884698,donec ut dolor -399326306,ac est lacinia -505145441,sapien varius ut -367387776,tincidunt eget tempus vel -716313501,eleifend luctus ultricies eu nibh -400260638,ultrices phasellus id -848645626,non -562385233,sed interdum venenatis -794779579,congue eget semper -555224189,mi integer ac neque -244358689,turpis integer aliquet massa -428233614,nam -364362389,donec posuere -561215404,vulputate justo in -163042931,ultrices posuere -703500439,fermentum justo -497502336,eu massa -980589136,in magna bibendum imperdiet nullam -521209871,ante ipsum primis in faucibus -979323889,ante -363740051,mi in porttitor -163525730,amet nulla quisque arcu libero -573654032,mauris lacinia sapien quis libero -937630299,nullam -687104754,tincidunt eu -246816785,diam id ornare -734651956,praesent blandit nam -371213587,tincidunt lacus at velit vivamus -896629644,rhoncus aliquam lacus morbi -277539473,aliquet -259901091,ut mauris eget massa -684198117,arcu -344762856,luctus nec molestie sed -329909264,semper -992058930,velit -900182585,vestibulum sit amet -810604567,mauris -874506641,tempus vivamus in felis -771521211,rhoncus aliquet -288580251,vel lectus -786623755,vitae quam -567476312,ultrices vel augue vestibulum -321120893,eget semper rutrum -748868438,sociis natoque penatibus et magnis -700575962,ipsum dolor -137910090,ut dolor -840004479,pulvinar nulla pede -249189672,varius -646640228,metus vitae ipsum aliquam -362741909,at turpis donec -916888130,eget -119304951,orci nullam molestie nibh -632691855,dolor vel est donec odio -115118134,molestie hendrerit at -911832102,diam erat fermentum justo nec -440387258,nunc viverra dapibus nulla suscipit -445860494,erat eros viverra -104138361,sem fusce consequat nulla nisl -804583110,morbi non quam -603012794,lectus -714670581,habitasse platea dictumst -808531097,odio consequat varius integer -325430318,eu est congue elementum in -849682546,curae mauris viverra diam vitae -230036553,lacus at -258249742,pede ullamcorper augue a -601735571,platea dictumst morbi vestibulum -601179541,at ipsum ac tellus -301789667,velit eu est congue elementum -876733398,suscipit -586016939,mi -473573117,elit -148988504,velit -570430313,proin leo odio porttitor -157963281,tellus nisi eu orci -966303868,lectus in quam fringilla rhoncus -756773901,lectus pellentesque -958089613,libero non mattis pulvinar -296017485,donec -576257295,vel dapibus at diam -259140403,consequat -487926538,est risus auctor sed -980347477,posuere cubilia -368632017,aliquam non mauris morbi non -444132165,nullam porttitor lacus -980442933,luctus -738334468,phasellus sit amet erat -477946412,congue etiam justo etiam -939269903,facilisi cras -322178490,justo -959005861,ac tellus semper interdum mauris -225046880,turpis integer aliquet massa id -145147703,proin -833637051,vel nisl duis ac nibh -263435832,enim -342495855,in hac habitasse -825669350,imperdiet et commodo vulputate -426667383,elementum -996192727,in eleifend quam -637200223,fermentum donec ut mauris -709855590,quis -638008567,nisi at nibh -311886291,maecenas leo odio condimentum -493610668,velit -621419139,interdum mauris non ligula -568410930,interdum in ante vestibulum -131678416,dapibus augue vel -174488146,et ultrices posuere -394401230,dictumst aliquam augue quam -760959784,scelerisque quam turpis adipiscing -657347893,id lobortis convallis tortor -325827364,cubilia curae donec pharetra magna -467325893,habitasse platea dictumst maecenas -166462841,in -792053333,aliquet maecenas -541591158,nulla suscipit ligula -347671432,vitae consectetuer -175718527,duis mattis -912651562,rhoncus sed vestibulum sit -582477527,pulvinar -538302265,sodales scelerisque mauris -530983211,amet nulla quisque arcu libero -989063758,eu massa donec dapibus -632405540,morbi ut -209001522,risus praesent -676635403,etiam vel -144041271,nunc rhoncus dui vel -948908784,vestibulum velit id pretium -278210987,eu nibh quisque id -232072690,sapien in -125878513,consequat nulla -876977530,quam fringilla -465986269,etiam faucibus -652451163,leo rhoncus sed -687285114,sed -416008946,consequat dui -451818621,eu sapien cursus vestibulum -561590446,nisl -278290617,ante ipsum primis in -657970548,bibendum morbi non quam nec -420362218,donec quis -433144704,condimentum neque sapien placerat ante -791638784,mattis -179131175,purus sit amet nulla -463203276,mauris laoreet ut -220743217,aenean auctor gravida sem praesent -304362944,elit -661337880,sodales -563645444,tellus nulla ut -456561576,duis ac nibh fusce lacus -536968522,ac lobortis vel dapibus at -844183910,neque vestibulum eget vulputate ut -916991925,magna vulputate -513786663,malesuada in imperdiet et commodo -625582110,tincidunt eget -928638902,turpis -418151668,aenean auctor gravida sem -395705224,sit amet -925281947,tempus vel pede morbi -384753521,consequat nulla nisl nunc -389929624,nisl duis ac nibh -833805735,aliquet -824849427,aliquet -807246796,vel nisl duis -778151232,mauris viverra diam vitae -827224345,aliquam augue quam sollicitudin vitae -510396676,mauris laoreet ut -578878117,non mauris morbi non lectus -293416873,morbi porttitor lorem id -973254038,convallis nunc proin at -633825976,rhoncus dui vel sem sed -173337207,aliquam lacus morbi -127678874,a -974617877,auctor -910573706,nulla pede ullamcorper augue -893363167,etiam justo etiam pretium -107769588,rhoncus dui -356234593,platea dictumst maecenas -879415346,cursus urna ut tellus nulla -934872836,volutpat eleifend donec ut dolor -317027852,interdum in ante -984162147,diam neque vestibulum eget vulputate -560096473,lacinia -917690275,arcu adipiscing molestie -275458107,non -676631735,consectetuer eget rutrum at -707834270,in magna bibendum imperdiet nullam -660302011,ultrices posuere cubilia curae -924009848,etiam justo etiam -442689793,ridiculus -662802224,viverra dapibus -887989362,elit proin risus praesent lectus -250735682,sapien in sapien iaculis -420814101,vitae quam suspendisse -697317038,interdum eu tincidunt in leo -862524618,sit amet -146159545,vestibulum proin eu -925792290,sit amet lobortis sapien sapien -996170397,semper -567106248,imperdiet et commodo -430337796,bibendum morbi non quam nec -504932955,a nibh -650357224,posuere cubilia curae mauris -456600409,mattis egestas -489408031,non mauris -486358562,integer aliquet massa -384666771,at velit -488886436,in -846824240,consequat ut -326315040,pede ullamcorper augue a -660309442,ut erat -259231945,tortor duis mattis egestas metus -281085154,ligula in lacus curabitur at -949597131,bibendum -983454700,in imperdiet et commodo vulputate -140910687,ultrices posuere cubilia -692655940,habitasse platea dictumst maecenas -492893069,leo odio condimentum id luctus -740461197,ipsum praesent blandit lacinia -647502328,donec semper sapien a -204323305,nulla tellus -548879132,nisi volutpat eleifend donec -677326386,nisi -951698574,volutpat convallis morbi odio odio -270018846,orci eget -848653141,donec ut mauris eget massa -146394189,ut -655688895,curae duis faucibus accumsan -631016584,ultrices erat -150902861,nulla -773484327,vulputate vitae nisl aenean -523705908,mauris lacinia sapien -728843910,adipiscing elit proin risus -171445786,nisi nam ultrices libero -919453274,diam -606845764,varius ut -750624598,non quam nec -789304478,curae -615991446,eget congue -735752438,odio curabitur -736957814,fermentum donec ut mauris -338598295,nisl venenatis lacinia aenean sit -139776036,congue eget semper -263201063,eget tincidunt -869085498,dapibus at -851070268,at velit eu est -305551836,interdum mauris non ligula pellentesque -691531228,vulputate luctus cum sociis -759447967,sit amet -869371191,quis justo maecenas rhoncus -370965560,felis donec semper -174054572,praesent blandit lacinia erat vestibulum -634860652,parturient -275883082,amet sapien -621322606,quam pharetra magna ac -523719521,odio cras -312496159,bibendum -201669665,sit amet turpis -519761627,enim -547749051,vestibulum ante -163737144,augue vestibulum -853195341,at diam -419207104,sit amet -681116541,ornare consequat lectus in -588224417,quam suspendisse potenti -594874548,magna bibendum imperdiet nullam orci -502823279,in -730960050,congue risus semper porta -458167343,lacus purus aliquet at feugiat -476896514,curae -849759883,nisl nunc rhoncus -418980503,luctus tincidunt nulla mollis -427625994,cras non velit nec -385026792,luctus et ultrices posuere -656545696,quam nec dui -928346974,aliquet -345808882,imperdiet -824069407,sem fusce -321700428,sed interdum venenatis turpis -576919523,ut dolor -983010338,integer pede -340275120,a nibh in quis -133263734,et -299387560,diam in -218163675,diam in magna bibendum -589520918,vestibulum eget vulputate -158730954,nulla neque libero convallis eget -237084331,at ipsum -859729904,augue -598987547,dolor morbi vel lectus -784129785,diam nam tristique -981543617,sapien dignissim -511929671,nulla -866439985,tellus semper interdum mauris -922297832,ut dolor morbi -813172020,ut -596049273,sapien cum sociis natoque -759574443,etiam faucibus cursus urna ut -987396221,in -378644046,duis -689740545,pede ac diam cras pellentesque -127279498,ipsum primis in -602800361,odio cras mi pede -381692672,dis parturient -885169262,lacus morbi -513316260,ligula sit amet eleifend pede -805814700,in -344513791,vestibulum -848317744,vestibulum ac est lacinia -232855026,nisl duis ac -583079974,felis ut -781428393,lacus at turpis donec -957401143,neque duis bibendum -837669447,tristique tortor -896162992,placerat ante nulla -567287700,consequat ut nulla sed -534074012,justo -491818522,ultrices posuere -818807826,gravida sem praesent id -536675182,vehicula condimentum curabitur -136561037,nisi -809106195,leo pellentesque ultrices mattis -360499325,condimentum id luctus nec molestie -483663848,semper porta volutpat -745449318,quam -173479709,luctus tincidunt -346220637,quam pharetra magna -766924720,vulputate nonummy -110050853,bibendum felis sed -356445411,vehicula condimentum curabitur in -393746465,eros elementum pellentesque quisque porta -457919764,feugiat -463086148,odio condimentum -351336547,odio curabitur convallis duis consequat -437353409,cursus urna -209513431,mi in porttitor pede justo -379472574,mauris viverra -243615399,vestibulum sed magna -595272838,in -812457250,ligula pellentesque ultrices phasellus -599128201,suscipit nulla elit ac -266577655,feugiat non pretium -871030732,ligula vehicula consequat morbi -745306885,sit -948132773,nascetur ridiculus mus -155085176,justo lacinia eget tincidunt -465557850,dolor morbi -899560836,augue -271647681,purus sit -282747271,curabitur convallis duis consequat -229238805,libero rutrum -345110645,dis parturient montes nascetur ridiculus -217698524,purus eu magna vulputate -338974345,at feugiat non pretium -577702536,ante ipsum primis in faucibus -901119403,orci luctus et -884664453,potenti cras -858388507,penatibus et magnis -532004065,dolor sit amet -786662113,nec dui luctus -125211394,non pretium quis -293681042,erat volutpat in congue -565652459,hac -504933641,pretium iaculis justo -832675724,tellus -660388582,tempus -891011858,praesent -707157630,eu orci mauris lacinia -347928675,pharetra magna ac consequat -136587887,magna ac consequat -194920670,leo rhoncus sed vestibulum sit -694013285,aliquam lacus morbi quis tortor -919920491,et -700000121,vel -796426680,est phasellus sit amet erat -291267055,id lobortis convallis tortor risus -391314513,congue vivamus metus -861013621,ut -617818716,posuere -835588281,eu est congue elementum in -425346455,dictumst aliquam augue quam -774429759,quis justo -850613664,mauris laoreet -787328124,lacus morbi quis -929350433,porta volutpat erat quisque -732459461,libero -709864515,venenatis -410136011,amet cursus -797701214,convallis duis consequat dui -663843153,nulla ut erat id mauris -840146553,vel nulla eget eros -639540819,maecenas -668489926,diam vitae quam suspendisse -370303877,arcu adipiscing molestie hendrerit at -681081713,integer pede justo lacinia eget -801320123,sit -693742446,fermentum -120248090,etiam justo etiam -986607527,ultrices -551884074,lectus in -997738389,adipiscing elit proin risus praesent -382794067,amet -814582624,in imperdiet et commodo vulputate -469583304,lacus -948262696,enim -661016991,luctus cum sociis natoque -465577875,porta volutpat quam -450665789,ridiculus -680186072,ut volutpat -512575934,ut massa quis -510603952,congue -906425318,potenti nullam porttitor lacus at -685558825,sed -740093821,proin risus praesent lectus vestibulum -177229353,justo sollicitudin -928290167,phasellus in felis donec -624296283,aliquam sit amet diam -224831326,ut ultrices -261705547,pulvinar lobortis est phasellus -492514637,sit amet nunc viverra dapibus -326926472,sed tristique -435656592,accumsan tortor quis -470807611,ante -989561964,orci -752487581,magna vulputate luctus cum -674436065,vehicula condimentum -136639543,pede justo eu massa -717522272,pulvinar sed -552237531,venenatis -469843163,aliquam -569509011,in -971716189,volutpat dui -242246361,integer aliquet massa id lobortis -106245344,ut nunc vestibulum ante ipsum -620121156,magna bibendum imperdiet -524831967,ac neque duis bibendum -571459991,non ligula pellentesque ultrices -783270365,nisl nunc nisl duis bibendum -378517876,justo eu -680330674,eu massa -419633871,accumsan -980118749,ut odio cras mi pede -938206433,nisl venenatis lacinia aenean -806027418,morbi porttitor lorem -732372463,enim leo rhoncus -559408326,nunc -297264646,facilisi -100488054,aliquam -206262720,augue a suscipit -752597157,fermentum justo nec condimentum neque -118528989,vel -503097819,sit -416165265,consequat metus -532616425,pellentesque viverra pede ac diam -869012400,pellentesque volutpat dui maecenas -446142499,nibh quisque -213763579,a ipsum -901806765,aenean auctor gravida sem praesent -322137060,maecenas rhoncus -712585183,sollicitudin vitae -388038682,ligula sit -756079567,nisi at nibh in -273202029,faucibus orci luctus -211452253,erat -289100461,felis ut at dolor quis -135616526,massa -411287879,sapien non -250524060,vel -802521760,venenatis turpis enim -728595029,purus -976802368,aliquam convallis -953778914,justo -399511695,accumsan tortor quis -383073081,praesent id -405022631,nisl duis bibendum felis sed -258452395,posuere felis sed lacus morbi -718917382,sit amet consectetuer adipiscing elit -273280814,nulla elit ac nulla sed -418500837,et ultrices posuere -601041101,pellentesque quisque porta volutpat -920031507,in quis justo maecenas rhoncus -207668312,pede lobortis -823693152,duis ac nibh fusce lacus -397490213,mattis egestas -371659307,nec sem duis aliquam convallis -222346666,amet cursus id turpis -806998030,a nibh in quis -184782091,lectus in est -262409119,nunc -752736325,amet nulla quisque arcu -548129387,dui luctus rutrum nulla -453711205,rhoncus dui vel sem sed -396724873,vestibulum vestibulum ante ipsum primis -805876060,proin -436357632,ipsum primis in faucibus -333627915,integer ac leo -201973480,nec nisi -908310538,volutpat in congue etiam -555124965,tortor sollicitudin mi -561631734,diam in magna -280467598,rutrum nulla nunc -119499517,dictumst maecenas ut massa quis -433524668,suscipit ligula in -573477305,in sapien iaculis congue vivamus -279819318,molestie hendrerit -473902929,placerat ante nulla justo -969455796,fusce posuere felis sed lacus -983704133,ut ultrices -953760448,nam -485364422,eleifend quam a odio in -809426626,mi in porttitor pede -474157603,pede posuere nonummy integer -329898179,tellus semper interdum mauris -100634955,maecenas rhoncus aliquam -814034045,sapien a -266749269,in libero ut massa volutpat -767190056,nisi venenatis tristique fusce -462486383,vel lectus in quam -102125464,in quis justo maecenas -934476330,viverra dapibus nulla -249161478,in est -484091775,augue -250112755,rhoncus mauris -636942005,rutrum nulla nunc purus -488626101,sapien varius -131056695,augue vestibulum ante -632142751,ut nunc vestibulum -804384536,suspendisse accumsan tortor quis turpis -476407193,augue luctus tincidunt -966204391,ipsum dolor sit amet -332880825,praesent blandit lacinia -862526597,volutpat dui maecenas tristique -883608620,lacinia -554706837,vivamus tortor duis mattis egestas -805230245,aliquam sit amet -553019015,sit amet -506947815,elit -887093589,orci luctus et ultrices posuere -176439205,leo rhoncus sed vestibulum -649547269,semper est quam pharetra -154895995,justo eu massa -929343795,nullam molestie nibh -852551687,scelerisque quam turpis -867292881,tellus nisi eu orci -580221155,rutrum ac lobortis vel -711406840,dapibus at diam nam -827345239,in felis -149175580,volutpat sapien arcu sed augue -565881318,dui -179750348,quis orci eget orci vehicula -257264412,ac nulla -307443261,a -268611612,in hac habitasse platea dictumst -295953303,massa -540673566,hac habitasse platea dictumst aliquam -827949916,interdum in ante vestibulum ante -558410970,luctus ultricies eu -937505374,nulla neque libero -577175465,at velit eu -377393931,id justo -965979682,quis -273494557,enim lorem -878555841,nulla sed vel enim sit -214558719,convallis duis consequat dui nec -610940730,lobortis ligula -544742852,libero -940744061,libero -664409250,ipsum aliquam non -135247604,varius -956030922,congue risus semper porta volutpat -902060672,augue a suscipit nulla elit -278063000,vel accumsan tellus -194741000,sollicitudin vitae consectetuer eget -777030406,fermentum justo nec condimentum neque -870618556,in faucibus -645744747,vestibulum sagittis sapien cum -247304057,metus -910365940,accumsan tortor quis -887538194,vitae nisi -529534863,nunc commodo placerat praesent blandit -591890514,ut -298471036,quam pede lobortis ligula sit -908009690,risus auctor sed -312312225,semper -218417496,felis donec -741527988,curae mauris viverra diam vitae -671073175,nulla neque libero convallis -596032578,velit id pretium iaculis diam -354322564,aliquam -844869711,quis -787720362,massa donec dapibus duis -278564860,nisl -664728221,sapien -423282931,eu est congue elementum -516420421,nulla nisl -904394317,in libero ut massa volutpat -873819503,eu magna vulputate luctus cum -924827630,rhoncus aliquam lacus morbi -736761201,leo rhoncus sed -824373490,mauris enim leo rhoncus -485233711,aliquam convallis nunc proin at -965389669,felis sed interdum -220205551,dui proin leo odio -501839170,non velit nec -225566513,luctus rutrum nulla -620899127,quis odio consequat -850133442,dui luctus rutrum -609779943,orci -326410578,amet nunc -952186526,id -159656986,nullam varius nulla facilisi -842500390,suscipit nulla elit ac nulla -874066991,justo eu massa donec dapibus -525609294,dictumst aliquam -308524837,ornare consequat -754922857,sociis natoque penatibus et -613069323,adipiscing elit proin interdum mauris -857177820,massa -851428227,ac nulla sed vel -793629795,felis donec semper sapien -517232699,ante -772754222,quis libero nullam sit amet -773658809,eros -267644793,tempus vivamus in felis eu -221848115,nam ultrices libero non mattis -211128958,nibh -986985896,ligula in lacus curabitur -839180763,dictumst aliquam augue quam -415663138,a odio -227001310,a -136880898,consectetuer -879171149,venenatis turpis -705481679,amet eros suspendisse accumsan tortor -448867925,primis -998961828,velit vivamus vel nulla -278974074,fringilla rhoncus mauris enim -311961525,ipsum dolor -306261007,augue quam sollicitudin vitae consectetuer -605252519,amet -972915526,lacus curabitur at ipsum ac -859035037,nunc viverra -634187082,ultrices erat tortor sollicitudin -176116244,vitae mattis -426969969,sed justo pellentesque viverra pede -287728763,pellentesque at nulla suspendisse -376263936,congue elementum in hac habitasse -423888130,velit id pretium -679182028,posuere felis sed -611989270,erat tortor sollicitudin -553293454,non quam nec dui luctus -609436712,tempus sit amet -315983668,ultrices -124711771,feugiat non pretium quis -750042065,interdum mauris ullamcorper purus -944698601,rhoncus -639589789,ultrices aliquet maecenas leo odio -917941858,sed justo pellentesque -471427195,nisi venenatis -446984318,ornare -884131390,est donec odio justo -858464456,sit amet nunc viverra -891001970,nascetur ridiculus mus vivamus -385817870,ante -289760711,sed vel -799770454,convallis eget eleifend luctus -783529071,cum sociis natoque penatibus -294634378,in imperdiet et commodo vulputate -509156661,quam nec dui luctus -839134703,suscipit a feugiat et eros -410727335,proin -600490939,aliquam lacus morbi quis tortor -613615342,dictumst etiam -913977248,eu orci mauris -704376002,cubilia curae donec pharetra magna -432271956,ligula pellentesque ultrices -393128433,curae mauris viverra diam vitae -457710598,justo -799310976,ipsum -747156004,massa quis augue -598841279,felis fusce -704150999,ornare consequat -531303208,sapien ut nunc vestibulum ante -451466302,magna at nunc commodo placerat -379374617,pede justo lacinia -628839738,lorem -255786875,at dolor quis -565120897,faucibus cursus urna ut tellus -136679486,pulvinar sed nisl nunc -188202073,integer ac neque duis bibendum -515886966,laoreet ut rhoncus -796996095,duis -836230493,dictumst -171666022,in -997391591,praesent id massa id nisl -858328399,viverra pede -945468238,tortor -863844887,donec diam neque vestibulum eget -509456064,maecenas rhoncus aliquam lacus -855015160,in -690049623,leo maecenas pulvinar -582480189,sapien varius ut blandit -656398142,mauris non ligula pellentesque -719982881,orci -503059303,sed interdum venenatis -200076004,est congue elementum in hac -988249464,ante vestibulum ante -580271562,at nulla suspendisse potenti cras -625882501,sem sed sagittis nam -576340992,mattis nibh ligula nec sem -609628731,tellus in -324624597,donec quis orci -671496024,sem duis -111475350,lorem quisque ut erat curabitur -243324483,nam dui -114576219,purus aliquet at -167914796,suspendisse -720131000,posuere nonummy integer non -203219341,volutpat in congue etiam -399921849,diam id ornare imperdiet sapien -409503709,nisl ut volutpat -675526159,donec dapibus duis at velit -590832722,turpis -187927780,odio consequat varius integer -212310618,quis turpis eget elit -767036538,vestibulum sit amet cursus -487613279,tellus semper interdum mauris -945986484,vitae nisi -526593436,dictumst maecenas -367712817,porta volutpat erat -574241391,amet erat -578595550,leo odio condimentum id -210963931,dolor -419592648,hac habitasse platea -595226074,in leo maecenas pulvinar lobortis -280761021,nulla justo aliquam quis -836065706,lacus -326155041,ligula vehicula consequat morbi -976461608,est quam pharetra magna ac -229240233,nam -780115534,sapien non -252639361,hac habitasse platea -808746075,quam suspendisse -498413728,sit amet cursus id -176753404,faucibus orci luctus -511589650,sem fusce -823848022,diam -278397547,vel sem sed sagittis nam -847429660,cras non -717449631,at velit eu est congue -623503794,quis tortor id nulla ultrices -406293310,arcu libero rutrum ac lobortis -984284058,in felis donec -119264072,nulla suscipit -689099237,nulla nisl nunc nisl duis -294592346,donec ut mauris eget massa -546195048,ipsum primis in faucibus -881775699,at nunc commodo placerat praesent -470554913,sapien varius ut -659916082,morbi quis tortor id nulla -433712298,ipsum aliquam non mauris morbi -306996974,luctus et ultrices posuere -652044964,venenatis non sodales -120952325,faucibus cursus urna -152819239,augue aliquam erat volutpat -759849898,ut odio cras mi -667840939,donec pharetra magna vestibulum -391461349,pede -213517411,tristique est et tempus -467473663,id -928813500,pellentesque quisque -247840290,augue aliquam erat volutpat -611375991,nisi venenatis tristique fusce -670880739,eget elit sodales scelerisque -334935200,felis donec -473230521,quam pharetra -226833125,nunc rhoncus -122015929,eleifend luctus ultricies -438669063,nec dui -997336799,ut massa volutpat convallis -659847262,imperdiet et commodo vulputate -495673198,magna -289388367,diam in magna bibendum imperdiet -461352762,proin interdum mauris non ligula -344762491,posuere felis sed lacus -823184495,quam a -119672435,orci luctus -970859259,libero nullam sit -637933935,consequat ut nulla sed -482902488,mauris sit amet -304634294,nulla ac -466361724,magna ac consequat -863874433,dolor sit amet consectetuer -519745280,faucibus orci luctus et ultrices -810895548,leo -321008650,sem praesent id massa id -716944199,penatibus et -123073602,est -169637597,ut blandit non interdum -765732059,nascetur ridiculus -675759910,ut suscipit a -187235009,nunc -211727029,vestibulum sagittis sapien cum sociis -600062947,aenean lectus pellentesque -952874856,magnis -989495867,lacus at velit vivamus vel -404632131,sem fusce consequat -224402539,elementum nullam varius -857346694,duis ac nibh fusce -119149673,duis bibendum felis sed interdum -374721495,aliquam augue quam -451014695,ultrices posuere cubilia curae -320291206,mauris viverra -160294030,eget -249212386,nascetur ridiculus mus etiam vel -636871643,proin -444977485,ac est lacinia -376838968,turpis integer aliquet massa -377685424,nulla facilisi cras -239875401,in -419655675,ut nulla sed -890133367,aenean sit amet justo morbi -417432664,nulla nunc purus phasellus -711709627,pretium nisl ut volutpat -654638713,eros suspendisse accumsan -615254174,quam pharetra magna ac -793501261,ultrices -846147700,facilisi -149854929,nunc viverra -457914290,lectus -235687416,cubilia -513291461,sed -450896530,consequat metus -320535599,non -212665151,rutrum nulla nunc purus -955481979,porttitor lorem id -493049051,sagittis sapien cum sociis -163564040,mauris -462997811,ultrices posuere cubilia -942446997,interdum venenatis -865380940,lacus -404711998,vivamus tortor duis mattis -821746618,turpis -450640055,porttitor -943514507,ac neque duis -153534644,non lectus aliquam sit -236293109,est -545617665,vulputate -995956328,metus arcu adipiscing molestie hendrerit -503434485,integer tincidunt -782224848,massa volutpat convallis morbi odio -766393826,vestibulum quam -594131976,venenatis lacinia aenean sit -195823648,vestibulum ante ipsum primis -739458707,iaculis congue vivamus metus arcu -166666584,placerat praesent blandit nam -780578423,ac consequat metus -469178220,penatibus et magnis dis parturient -206936720,congue vivamus metus arcu adipiscing -477641799,sit amet diam in -674530615,elit sodales scelerisque mauris sit -242108600,lacus -878044784,sem duis aliquam convallis nunc -202426596,augue aliquam erat -201269663,potenti -577119257,sed -911718767,pretium iaculis justo in -807613525,pellentesque viverra pede ac -360298748,ut erat -284155127,sit amet consectetuer adipiscing elit -990335084,sit amet turpis elementum ligula -938410182,mus vivamus vestibulum sagittis -347086175,condimentum curabitur in libero -224720714,eu -142991131,sem duis aliquam convallis nunc -764156392,molestie hendrerit at vulputate -266972757,mollis molestie lorem quisque ut -708534310,rhoncus aliquet pulvinar sed nisl -466652711,duis bibendum felis sed interdum -301299883,velit vivamus vel -409337256,ultrices -296635692,id consequat in consequat ut -530654428,sit -576763973,nullam molestie -758645679,dictumst maecenas ut massa -832926809,mauris ullamcorper purus sit amet -784708228,et ultrices posuere cubilia -788131848,orci luctus et ultrices posuere -518422540,ultrices posuere cubilia curae duis -810021374,nibh in lectus pellentesque at -780186717,sed justo -254459159,lorem vitae mattis -685560277,consequat -366447001,sit amet -532993823,justo maecenas rhoncus -951417570,cubilia -430504532,dolor vel -167903534,in -319922948,felis -733683508,vulputate elementum nullam varius -359290431,a libero nam dui proin -416443566,vel sem sed sagittis nam -768028138,ultrices -507136474,imperdiet nullam -399600523,vel enim sit -162886092,id consequat in consequat -302977415,vel sem -126878653,aliquam lacus -515540305,at dolor quis -558831922,vehicula condimentum curabitur in libero -123596971,habitasse platea -170264351,orci mauris lacinia sapien quis -978768495,purus eu magna -395544016,sapien cursus -983400106,amet nulla -177953813,mauris laoreet -319291105,lacinia erat -641522081,turpis elementum ligula -146144925,orci mauris lacinia sapien -966016364,cras mi pede -516193868,sollicitudin ut suscipit a -901298908,bibendum felis sed -763231059,pellentesque ultrices mattis odio donec -895802235,eros vestibulum ac est lacinia -570485346,mollis molestie lorem quisque -777770639,quis libero nullam sit amet -861304282,ut -230581650,cursus urna ut tellus nulla -961989761,nulla eget eros elementum pellentesque -368347237,odio condimentum id -577332774,nunc -709285127,adipiscing elit proin risus praesent -615807147,lorem -627330966,habitasse platea dictumst aliquam -512427793,massa volutpat convallis -667070637,et ultrices posuere -601556878,condimentum -836421540,cum sociis natoque penatibus -484190222,elementum eu interdum eu tincidunt -678130633,orci luctus et -467050604,vestibulum -503170941,diam id ornare imperdiet sapien -910152661,magnis dis parturient -256079125,morbi non lectus aliquam -241331847,etiam pretium -928350715,nam ultrices -877038556,laoreet ut rhoncus aliquet -440779307,tellus in sagittis dui vel -196963140,velit eu -908706025,velit -374354522,eget eros -119471270,justo morbi ut odio cras -419108143,volutpat -390582187,lobortis est phasellus sit amet -583542733,semper rutrum -173625602,elementum in -609246495,sollicitudin mi -155830830,praesent id -295400681,nullam -432817499,in lacus curabitur -110655314,morbi sem -644619277,placerat ante -356187484,interdum venenatis -129580668,mi pede malesuada -683591565,mi sit -845222895,ante -756170047,vestibulum sagittis sapien cum sociis -769134305,lorem quisque -381580580,at turpis donec posuere metus -760320741,in eleifend quam -725478140,accumsan felis -515639176,morbi odio odio elementum -614786267,imperdiet sapien -224010129,vivamus tortor duis -418301018,bibendum morbi -261779484,nec -650996470,iaculis congue vivamus metus arcu -884670592,nisi nam ultrices -746829283,vel sem sed -251245711,eu tincidunt in -503972216,mauris non ligula pellentesque ultrices -181939924,dapibus -855608458,vel ipsum praesent -400710203,magna bibendum -988522705,integer -360802337,lectus aliquam sit amet diam -319831800,arcu -768998857,sit -466269173,platea -723586309,neque duis -938247967,ultrices vel augue -826167242,ultrices -844478872,vestibulum -526698474,pede ac diam -377045798,pede lobortis -688677260,tortor duis mattis egestas -705605847,hendrerit at vulputate -210192647,ornare imperdiet sapien urna pretium -146478869,orci luctus et ultrices posuere -953271525,augue aliquam -475137952,non mattis pulvinar nulla -495077507,nisl duis bibendum -887365632,gravida -438268298,platea dictumst maecenas -990596505,et commodo vulputate -699953570,tortor sollicitudin mi sit amet -901428516,ac lobortis -484891556,in -595085153,vitae nisi nam ultrices libero -707212775,dolor quis odio -713747684,erat vestibulum sed magna -296389562,penatibus et magnis dis -441047329,curae mauris viverra diam vitae -843985409,vestibulum -740432771,consectetuer adipiscing elit -245366391,parturient montes -307056166,morbi vel lectus -906114784,mi -885635448,a -919730943,pede -645893306,vitae quam suspendisse potenti nullam -964343399,pretium iaculis diam erat -593469488,porttitor lorem id ligula suspendisse -950386457,magna bibendum imperdiet nullam -997985297,nunc vestibulum ante ipsum primis -901496156,vulputate vitae -425451570,enim sit amet nunc -225145673,penatibus et magnis -555530207,a odio -822765313,mi integer ac neque duis -721826214,amet diam -227553864,quam -356026837,in quam fringilla rhoncus mauris -681867568,quis odio consequat varius -374474849,morbi sem mauris laoreet ut -525246995,consequat -118055335,odio cras -708984084,in hac habitasse -291767013,lobortis sapien sapien non mi -746687698,dapibus at diam -109498882,diam -203928933,amet sem fusce consequat nulla -793836756,tortor sollicitudin -804097003,laoreet ut rhoncus aliquet -671457792,duis bibendum felis -129666549,lacus at turpis donec posuere -595006850,ridiculus -199693437,duis bibendum morbi non -392523292,nisl ut volutpat sapien -954672444,felis eu sapien -509923363,eget vulputate ut -917391825,rhoncus aliquam -819383573,accumsan odio curabitur convallis -651245828,aliquam lacus morbi -499992740,fusce -101303562,orci -237181272,nulla mollis -881878463,magnis dis -254040138,pretium nisl -662235112,mauris ullamcorper purus sit -403018721,magnis dis -376700509,ut suscipit a -460620637,id lobortis -465965069,bibendum -181517569,convallis morbi odio odio -474750482,ultrices -646086833,sapien iaculis congue vivamus metus -701095477,nibh in hac habitasse -353228434,duis faucibus -755158321,aliquam quis turpis eget -831450508,pede -705310764,ac nulla sed -697220778,penatibus -901719314,curae donec pharetra magna vestibulum -976493357,orci luctus -704870439,non -395615390,sed interdum venenatis turpis enim -818770664,at nulla suspendisse potenti -259436258,integer non velit donec -423659019,libero non -305408091,tortor -757706962,quam pharetra magna ac consequat -692814853,sed vestibulum -386986090,cubilia curae nulla dapibus dolor -146139737,id ornare -592505469,tempor turpis nec euismod -920870668,vulputate -473020239,integer -549744211,mus vivamus vestibulum sagittis -657716355,dis parturient montes nascetur -818203514,maecenas tincidunt lacus at -514641124,eleifend quam a odio in -421605907,in hac -709765264,semper -526916632,proin eu mi nulla ac -604268617,diam cras pellentesque volutpat dui -547908036,proin -778478590,faucibus cursus urna -382269880,ipsum praesent -996431994,neque libero convallis eget eleifend -455887216,quis libero nullam sit -298166342,morbi -112830102,eu magna vulputate luctus -565531817,ac enim in tempor -856626627,sapien urna pretium nisl ut -113602334,at dolor quis -716709944,at feugiat non pretium quis -774611329,enim lorem ipsum dolor sit -766026589,nulla ultrices aliquet maecenas leo -733670160,sapien urna pretium nisl ut -963997076,vitae nisl aenean lectus -300918294,auctor gravida sem -657816594,justo morbi ut odio cras -738188888,semper porta volutpat -768596228,blandit -582621297,eu nibh quisque -586678660,vestibulum -204657519,fermentum donec ut mauris -676975140,aliquet maecenas -626799846,nisi volutpat eleifend donec -984814187,viverra diam vitae quam -352298000,ut -346952687,convallis eget -730358274,lorem ipsum -641181810,integer tincidunt -179740782,proin at turpis a pede -620857518,venenatis tristique fusce congue diam -135153347,ante vel ipsum praesent -876860036,convallis tortor risus -213712731,nisl duis bibendum -171105545,a feugiat et eros -460214176,sollicitudin ut suscipit a feugiat -106384471,leo pellentesque ultrices mattis -296591222,leo odio porttitor id consequat -590145589,arcu adipiscing -945047619,nisl duis ac nibh -352492504,in congue -896992242,porta volutpat quam -245056146,quis -472268139,blandit nam -607310379,in hac -373285642,dolor morbi -619555775,ut -460803182,convallis eget -868680599,sem fusce consequat -766218166,mi nulla ac enim in -484011403,quam -166628774,lectus suspendisse -383328212,bibendum -188380759,sed -291416589,ante -401547654,morbi porttitor lorem id -329815121,nam congue risus semper -877270240,vivamus metus -984305561,pulvinar lobortis est phasellus -877219684,lorem quisque -630135275,nullam varius nulla facilisi cras -640851118,sagittis -649466229,erat vestibulum -986078010,parturient montes nascetur -432950004,mattis egestas metus aenean -177336112,est -202872596,nam congue risus semper porta -317178870,in quis justo maecenas -747756697,quis odio consequat -778949679,erat vestibulum sed magna -601638857,rutrum at -392737677,consequat lectus in est -682041823,vivamus tortor duis mattis -295214670,dui maecenas -146011180,imperdiet nullam orci pede -112969730,non sodales -615132605,sit amet lobortis sapien -716042547,donec dapibus duis at -869498133,hendrerit at -304958354,quam sollicitudin vitae consectetuer -161059416,id lobortis -488527031,odio porttitor id consequat -379955619,tortor risus dapibus augue -749165652,ipsum praesent blandit -264570250,ligula suspendisse ornare consequat lectus -230982939,ut volutpat -982416113,luctus tincidunt nulla -177326948,nunc viverra -823031807,vestibulum ante ipsum -896466408,habitasse platea -455854570,ut -672865156,interdum venenatis turpis -386469793,eu tincidunt in -718351532,volutpat sapien arcu sed augue -316410546,sit amet consectetuer adipiscing -552331830,diam -264352044,nullam sit amet -960057498,in libero ut -212949866,tempus -541828446,ac -185559503,quam sollicitudin vitae -353593221,ante -387257402,convallis eget eleifend luctus -765332177,porttitor lacus at -530291091,neque duis bibendum morbi -736279829,ligula vehicula consequat -897358362,tincidunt nulla mollis -788957153,magna -288971284,nibh -648308855,quis lectus suspendisse potenti in -715143479,enim lorem ipsum dolor sit -805264861,donec pharetra magna vestibulum aliquet -870549236,duis at velit eu -442824485,semper porta -159923774,nibh in quis -118451726,pretium iaculis -197899777,quisque erat eros -442123376,ut blandit non interdum -304524743,potenti nullam porttitor lacus -137062626,donec dapibus -372619958,non lectus aliquam sit -425326370,nulla ac enim -241552293,consequat morbi -914255648,orci nullam molestie nibh in -949209891,nisi nam ultrices libero non -761137578,consectetuer adipiscing elit proin risus -782824692,nunc proin at turpis a -439870488,vel -580691721,ac nibh -100346139,diam id ornare imperdiet sapien -833232683,mauris sit amet eros suspendisse -455094256,eget tempus vel -432690870,libero non mattis pulvinar nulla -338457150,sit amet consectetuer adipiscing -799770470,commodo vulputate -962792214,ante -732097669,platea dictumst morbi vestibulum velit -815749981,semper sapien a -302202898,non -130683764,velit vivamus vel nulla eget -111389324,odio in hac habitasse -298681160,ac enim in tempor -297135251,suscipit -999699947,mi -708351940,et ultrices -571886529,tempus vivamus in -849728622,dapibus nulla suscipit -984566192,donec vitae nisi nam ultrices -258855939,sagittis nam -624811341,nisi at -458470791,iaculis congue -178871136,nam -984452045,nam tristique -620214959,vestibulum ante -846937460,nulla sed -234114673,ut ultrices vel augue -463040725,augue -394255810,id luctus nec -785855383,nonummy integer -745175336,justo -747081591,ipsum -463250819,nibh ligula nec sem duis -522660091,venenatis tristique fusce congue -520272035,nulla elit ac nulla sed -115814240,nulla tellus in sagittis -638502657,donec -792240344,a pede posuere -492296769,hac habitasse platea dictumst -146262583,montes nascetur -807491261,sit amet diam in magna -782077421,in tempor turpis -484278236,enim -751746846,eget congue eget -218226858,ut odio cras mi pede -376672782,ut erat id mauris -986814411,dis parturient -887467312,amet sapien dignissim vestibulum -171864994,dapibus -943206518,vulputate nonummy maecenas -764146586,nunc viverra dapibus nulla -840935953,sodales scelerisque -413450302,nulla ut erat -497847145,eget rutrum at lorem integer -379242451,purus eu magna vulputate luctus -695112207,in congue etiam justo etiam -770263790,eu -473967117,odio elementum eu -865560907,pharetra magna vestibulum aliquet -675855646,nec euismod scelerisque quam turpis -601861410,nibh -222359132,sem -485850315,pede posuere nonummy -549510508,dictumst maecenas ut -335514718,in magna bibendum -684338952,hac habitasse platea -347450499,justo in blandit ultrices -883725407,nulla neque -737052289,pharetra magna -397918998,in congue -556306106,nibh fusce lacus purus aliquet -752245639,tristique fusce congue -366393392,justo in blandit ultrices -292033715,eros elementum pellentesque -976753937,dapibus nulla suscipit ligula in -948424062,sociis natoque penatibus et -543025267,quam pede lobortis -483059146,consequat in consequat ut -863582153,volutpat dui maecenas tristique est -189532214,orci vehicula condimentum curabitur in -537578409,quam -771810169,ultrices erat tortor sollicitudin mi -674935798,pede justo -985514234,odio odio elementum eu -198882133,interdum in -814862512,ac lobortis vel dapibus -913090297,mus -156932130,fermentum donec ut mauris eget -115025141,adipiscing -293388232,lectus -462981160,nulla sed vel -893454135,elementum nullam varius -544136691,ante ipsum -180633458,nibh in -602821007,luctus et ultrices posuere -324882253,nisl venenatis -558158706,sit amet sem -378805851,justo aliquam quis -930063339,pede posuere -775537200,mauris viverra diam -473025569,augue aliquam erat volutpat in -386854219,adipiscing -161499161,rutrum nulla nunc -312771411,orci eget orci vehicula condimentum -482603363,mus etiam vel augue -274676227,sapien varius ut blandit non -433808511,dolor sit amet consectetuer adipiscing -402057969,varius nulla -397441044,at -796510514,luctus et ultrices -905121841,lobortis ligula sit -283294667,arcu adipiscing molestie -334004771,justo in blandit ultrices enim -953610644,nulla integer pede -995107874,dui maecenas tristique est et -965408809,luctus tincidunt -963546041,in quam -677660735,mauris eget massa tempor convallis -967665237,sagittis sapien cum sociis natoque -718367816,quis -399101378,libero quis orci -573094049,aliquam -978837790,quis turpis -938577238,platea dictumst maecenas -467119982,duis bibendum morbi non quam -871449003,cursus urna ut tellus nulla -675110201,dictumst -543398151,in hac -754128541,pede libero quis orci nullam -881625439,sem sed -227776726,cum sociis -361603870,penatibus et magnis -500434010,congue risus -717523002,nulla justo -237061411,ac diam cras pellentesque volutpat -814443871,posuere metus -667008265,cubilia curae duis -138738625,eu pede -676597743,auctor gravida -269467748,augue a suscipit -494863939,cursus -490386032,quisque id justo sit amet -444058791,dui vel nisl duis -261955199,donec -761176136,convallis eget eleifend -251304273,mauris vulputate -744235368,sapien ut nunc -599262173,suscipit nulla elit ac -186051587,volutpat quam pede lobortis -775093180,tellus -922470762,aenean fermentum donec ut -448221174,odio condimentum id -945509037,tempor convallis nulla neque libero -413782971,aliquet -438347909,morbi -790046073,ligula nec sem duis -444760521,donec dapibus duis at -652245215,sem -229625944,donec diam neque -996568631,primis -401611774,pede -906699779,turpis elementum ligula vehicula -927428055,orci mauris lacinia sapien -705679563,porta -679933818,tellus semper interdum mauris ullamcorper -391330166,eu -691066017,ut tellus nulla ut erat -482213500,in quam fringilla -783900348,quam fringilla -403690491,nisl duis -938871477,mauris enim -140836107,suscipit ligula -660832551,consectetuer adipiscing elit -106673048,cras -795719083,sapien -462599340,suscipit a feugiat et eros -387839097,tincidunt in leo maecenas -342558790,nisi at nibh in -363817888,purus eu magna vulputate luctus -381282470,in sapien iaculis congue vivamus -741624660,est congue elementum in -382620729,neque -624310786,nibh fusce lacus -152667073,commodo placerat praesent blandit -949413342,metus sapien -844482090,sit amet -447409006,odio justo sollicitudin ut suscipit -818756980,ut volutpat sapien arcu sed -749923003,erat nulla tempus vivamus -706643650,ac -948992475,leo odio condimentum id luctus -374669029,in imperdiet et -445815758,euismod scelerisque quam turpis adipiscing -243006240,ante vivamus tortor -382149876,ut nunc -983799945,turpis sed ante vivamus -663901509,suspendisse potenti in eleifend -876850609,libero -352115268,metus vitae ipsum aliquam non -660939937,donec ut -369767077,hac habitasse -244029946,orci luctus et ultrices -105721212,sit amet nunc viverra dapibus -818585844,vel augue vestibulum ante ipsum -548925543,placerat ante nulla -365240739,vel -466693190,pretium iaculis -358525939,integer ac -709798469,cubilia curae duis faucibus -572488225,libero -674075933,mi nulla ac enim -339287423,fermentum donec -322005339,magna at nunc commodo placerat -722139058,pede libero quis orci -925406237,amet sapien dignissim -137209654,in magna bibendum imperdiet -523083361,aliquam -614443199,leo -730214277,id -528909160,eu interdum eu tincidunt -183063152,non mattis pulvinar nulla -211390305,orci -737930395,eget tempus vel -314479491,ut blandit non -693333933,augue a -662062460,ultrices enim lorem ipsum -614838785,ipsum ac tellus semper -530268802,at turpis donec -399146160,congue etiam justo etiam -984444787,penatibus -493843093,at -730124856,velit donec -416954306,elit -321452949,nunc viverra dapibus nulla suscipit -242781917,sed ante -537185849,ut volutpat sapien -213524379,nibh in quis justo maecenas -290630599,hac -638437315,semper interdum mauris ullamcorper -146896079,pharetra magna ac -573187589,lectus pellentesque eget nunc -301619006,pellentesque -868501834,sed sagittis nam congue risus -425470570,diam id ornare -329765328,eleifend luctus -505347024,cras pellentesque -490411460,mauris lacinia -199280156,quam a odio -556775224,consectetuer eget rutrum -449366538,tincidunt in leo maecenas pulvinar -859708749,praesent blandit nam nulla integer -107309983,viverra pede -553547325,nulla integer pede -304353160,interdum mauris -227963732,mi in porttitor pede -300561886,turpis eget elit sodales scelerisque -483297560,eleifend pede libero -433035039,purus sit amet nulla -154166203,nulla -503546185,pretium nisl -744011590,nullam orci pede -843240991,at velit vivamus vel -283987102,mauris -705891545,eros -528528761,tortor -237322500,mauris non ligula pellentesque -775179152,magna vestibulum -713943896,quis tortor id -755811040,libero nam dui proin leo -905356907,nec -514917614,felis eu sapien -501786814,in hac -670668647,posuere -905109301,eget eleifend luctus -351207160,nam -133902803,et -633816520,magna vestibulum aliquet ultrices -687189892,posuere cubilia curae nulla dapibus -409625192,turpis adipiscing lorem vitae mattis -276262075,aenean fermentum donec ut mauris -109074958,sagittis sapien cum sociis -755262335,at feugiat non -866810323,mauris vulputate elementum -819210477,mauris sit -455187117,sed -788594989,quis orci nullam molestie -611466241,a -308016847,maecenas pulvinar lobortis -413781147,mattis nibh ligula -657420140,at turpis donec posuere metus -173359755,eu interdum eu tincidunt -371211976,sapien iaculis congue vivamus -186320436,leo odio -653512689,parturient -560981510,justo etiam -951911915,dictumst morbi vestibulum velit id -677813699,venenatis non -280377088,nullam -140145662,donec -952835065,tempus vel -225071295,purus -129780844,facilisi cras non -747019543,lobortis convallis tortor -996885376,sapien -234921236,orci eget -428187132,praesent blandit -504983042,ligula nec sem duis aliquam -440593933,ipsum primis in faucibus -250890033,eu interdum eu -513174529,ligula pellentesque -499437763,id ornare -756594876,sit amet nunc -829454824,nullam orci pede -373147634,tortor id nulla -538563502,est quam pharetra magna ac -367541093,placerat ante nulla justo -872078268,neque sapien placerat ante -814923348,blandit non interdum in -524615022,etiam pretium -150801491,suspendisse potenti nullam porttitor -609890951,id nisl -607016916,a -950105716,consequat -539145786,massa quis augue luctus tincidunt -290449381,est -776644451,lobortis ligula sit -582321045,nisl aenean lectus pellentesque -888899122,ut odio cras mi -949816472,quis odio -295704961,metus vitae -756121886,fusce congue diam id ornare -917898475,mattis egestas metus aenean -795870296,lacus at turpis donec posuere -407762394,in quis justo maecenas -872388893,pede justo eu -611548917,molestie nibh in lectus pellentesque -608540584,et magnis dis parturient montes -361336384,aliquam convallis nunc -633829271,sed -127786394,vel pede morbi porttitor -885563976,justo etiam pretium iaculis -688247431,faucibus accumsan odio -263432381,sociis natoque penatibus -289758309,ligula suspendisse ornare consequat lectus -457297553,convallis eget eleifend luctus ultricies -798450516,morbi -985835354,nisi volutpat eleifend donec ut -736232320,justo in blandit ultrices enim -810064234,non mattis pulvinar -873073137,in quam fringilla rhoncus mauris -500791525,turpis enim -771582133,neque -767679206,nisi vulputate nonummy maecenas -407764809,convallis -108890810,magna vulputate luctus cum -212578217,suscipit ligula in lacus curabitur -883600630,nulla suscipit ligula in -312068984,lobortis est phasellus sit amet -111274976,tortor sollicitudin mi sit amet -919281790,tempus semper -356529152,phasellus id sapien in sapien -589823382,ipsum ac tellus semper -690082410,posuere cubilia curae nulla -622986206,libero nullam sit -149070162,vulputate justo in blandit -546758932,luctus nec molestie sed justo -657835652,tristique -810764769,ut ultrices vel augue vestibulum -592253443,aliquam non mauris morbi -702941079,mauris viverra -616875199,mauris lacinia sapien -122148541,penatibus et magnis dis parturient -187932397,faucibus orci luctus et -604974555,iaculis justo in hac -242582633,phasellus sit amet erat -774509623,vel -618017450,nibh in -854691741,non ligula pellentesque ultrices -679978739,nunc rhoncus dui -791732596,primis in faucibus orci -710131557,volutpat sapien arcu sed -986304210,sapien cum sociis -114697496,at velit vivamus -583232967,aenean fermentum donec ut mauris -534908864,potenti cras -696069809,praesent lectus vestibulum quam sapien -494891298,vestibulum ante ipsum primis -512694142,vestibulum velit id pretium -155940777,arcu sed augue -408388921,sit amet -408754758,tellus in -577906154,scelerisque quam turpis adipiscing -938279987,ultrices erat -421875713,massa id nisl venenatis lacinia -588493455,in tempor -377315716,vestibulum -892296933,rutrum neque aenean auctor gravida -371797304,in faucibus orci -200152722,ac consequat metus -874596494,vel -349589019,lacinia -436026848,non sodales sed tincidunt eu -913000281,nam dui proin leo -753856091,nulla integer pede justo lacinia -516909314,aliquet massa id lobortis convallis -931626957,primis in -272247523,dictumst aliquam -216684033,quam -332538785,quam -896816961,nibh fusce lacus purus aliquet -966958987,vestibulum ante ipsum primis in -320981635,libero -529298958,laoreet ut rhoncus -771365778,turpis donec posuere metus vitae -665971574,magnis dis parturient montes -530656434,proin -522139853,ridiculus mus vivamus vestibulum -155584612,ipsum ac tellus semper -948985576,justo etiam pretium iaculis justo -539960966,eu sapien cursus -610544842,faucibus orci -734660948,nec nisi volutpat eleifend donec -755927904,consequat varius integer ac leo -589176822,non quam nec dui luctus -731517231,at nibh -154467999,tristique in -898166911,vitae nisl aenean lectus -742319614,ante vel ipsum praesent -249469904,turpis -769549693,justo sit amet sapien dignissim -643210454,sociis natoque -866870582,eleifend quam a -746162737,fusce congue diam id ornare -868318433,sit -723090183,lorem -799488093,venenatis non sodales sed tincidunt -989362225,erat curabitur gravida -161232261,sed augue aliquam -659955221,in -719714590,magna -448993277,magna vulputate luctus cum sociis -386634676,sapien placerat ante -974729656,sapien dignissim vestibulum vestibulum ante -692225888,semper est quam -832656516,aenean auctor gravida sem -183149726,non -739669745,fusce posuere felis sed lacus -546103497,curabitur -701150974,consectetuer adipiscing elit proin risus -132423494,turpis -983762436,a ipsum integer a nibh -435247580,suspendisse potenti -550215001,quis turpis eget elit sodales -871707514,aenean sit amet justo -788294119,pede malesuada in -820423386,sapien quis libero nullam -900894397,ac nulla sed vel -561851704,odio cras mi -513493049,erat id mauris vulputate elementum -229706287,cubilia curae nulla -621429090,duis -179029222,vitae mattis nibh ligula nec -393497161,sem praesent id massa id -322753892,blandit -544135197,metus vitae ipsum -872488709,posuere cubilia curae -337518697,est risus auctor -262313069,ante vestibulum -997516632,nibh fusce lacus -991046667,sapien urna pretium nisl ut -875929986,in lacus curabitur at ipsum -178448966,id ornare imperdiet sapien -645775415,in quam fringilla rhoncus -531697731,interdum -643264230,et commodo vulputate -643217855,penatibus et magnis dis -144791702,nisl -980256796,vitae quam suspendisse potenti nullam -199589454,ligula pellentesque ultrices phasellus -458508072,orci nullam molestie -576169712,scelerisque mauris sit amet eros -404357820,in consequat ut nulla -164735952,nibh -787384217,cras non velit -710070472,amet eros suspendisse accumsan -700453212,luctus tincidunt -135762833,vivamus in felis eu sapien -980792593,posuere felis -568167623,molestie -996989610,urna pretium nisl -514537091,mi -358094993,in hac habitasse -913264912,lobortis -271382398,non velit donec -359882767,malesuada in imperdiet -795566275,integer -950371146,lobortis -950340475,dui luctus rutrum -525442797,ornare -668561587,in faucibus orci luctus et -833069510,lacinia aenean -272993465,amet turpis elementum ligula vehicula -919604515,eu interdum eu tincidunt in -820484461,sit -681427044,vulputate nonummy -738401139,nulla -416818722,sed -599342794,aliquam quis -592629792,hac habitasse platea dictumst aliquam -734628282,ullamcorper augue a -476937217,eu -830720854,leo odio -123567607,pulvinar sed nisl nunc -360322565,varius ut blandit non -119238668,non mauris morbi -380027334,eu nibh quisque id justo -888304994,libero rutrum ac -206776197,bibendum felis -491250198,est quam -844298527,lectus -547525409,justo -876648061,aliquam lacus morbi quis -108668588,aliquam quis turpis eget -658599880,elit sodales -708024585,sapien quis -268362975,blandit nam nulla integer pede -933634711,cubilia curae mauris viverra diam -938701661,scelerisque quam turpis adipiscing lorem -101731398,interdum mauris -893686643,sed magna at nunc commodo -659448084,nec -665340220,sapien iaculis -368685040,vel dapibus at diam -812846062,pulvinar sed nisl -136349738,ut ultrices vel augue vestibulum -568795677,vestibulum ante ipsum -878138846,in lacus curabitur at ipsum -402103462,integer -223077436,convallis nulla -894658195,penatibus et -358934137,at dolor quis odio consequat -360340193,habitasse platea dictumst maecenas -240978430,luctus ultricies -572093397,viverra dapibus nulla -845774551,eget semper -435585637,donec odio -119037248,turpis -655701215,consequat in consequat -865215017,in est risus -510514637,lorem ipsum dolor sit -337820847,nulla sed vel -842424936,ac -539827348,ultrices posuere cubilia curae mauris -562421051,orci mauris lacinia -532482488,fermentum justo nec -793241753,interdum eu tincidunt -984454336,fusce lacus purus -557363575,at lorem -400540497,accumsan -162875786,volutpat erat quisque erat eros -827286097,interdum eu tincidunt -877730516,est et -276275450,lacinia sapien quis -517120335,nisi at nibh -176316910,elementum in hac habitasse -602604051,aenean lectus pellentesque eget nunc -164465263,ridiculus mus etiam vel augue -688897648,nulla nunc purus -791880343,lobortis sapien -434544507,sagittis -702960603,congue -475422562,nisl venenatis lacinia -149725508,rhoncus dui vel sem -437788704,mus etiam vel augue vestibulum -182721869,mi sit amet lobortis sapien -614365409,luctus et ultrices posuere cubilia -325853518,in quam -108384348,aliquet ultrices -722242653,lobortis sapien sapien non mi -451192046,elit sodales -195660554,posuere nonummy integer non velit -187224288,pellentesque ultrices mattis odio donec -590569090,venenatis lacinia -901006081,adipiscing lorem vitae mattis nibh -344565461,nec condimentum neque -205008622,sapien arcu sed augue -211883148,porta volutpat quam pede -923810708,mattis -895004863,dui -853526724,posuere cubilia curae mauris -632133704,sed interdum venenatis turpis -673736341,mi integer ac -725468466,ac -929512795,sit amet consectetuer adipiscing elit -807925163,amet justo morbi -705053584,phasellus id sapien in -464854008,massa id lobortis convallis tortor -756623767,fusce consequat nulla nisl nunc -999872984,habitasse platea dictumst etiam -808377378,molestie lorem quisque ut erat -537914641,faucibus cursus -360906199,consequat -271004132,nunc rhoncus -666471658,fermentum donec -877138759,nam ultrices libero non mattis -751390703,sed augue -984382099,lobortis vel dapibus at -570882795,lacinia sapien quis libero -476145014,justo lacinia eget -473257986,libero -551773461,sed sagittis nam congue -664893851,ullamcorper augue a suscipit -616943710,at nulla suspendisse -415761318,nulla neque libero convallis eget -287616950,aliquet ultrices -121239086,id massa id nisl -926952463,platea dictumst -466433934,donec -359637114,volutpat convallis -751859053,in -506984250,luctus tincidunt nulla -428496954,quis orci nullam -369821795,dui vel sem sed -945427431,adipiscing -408975122,vivamus -179427948,luctus rutrum nulla tellus -179714237,nisi venenatis tristique -412448567,justo sollicitudin ut -821548536,vivamus in -250470979,purus -169527774,maecenas -260549165,elit proin interdum -527749767,tristique est et tempus -423601405,eget orci vehicula condimentum -975556940,in -121442011,aliquet ultrices -771165486,id consequat in consequat -487519099,luctus -630796311,donec semper sapien -941845630,erat tortor -917661978,nunc viverra dapibus -631483076,dis parturient montes -683242057,tincidunt ante -997876374,maecenas tristique -999701517,porttitor lorem id ligula -113376545,erat vestibulum sed magna -596948573,hac habitasse platea dictumst -775821505,tortor risus dapibus -793263705,eget eros elementum pellentesque -182128108,non interdum in -452392129,quisque erat eros -278106586,et eros -770828821,in -152594780,id nisl venenatis lacinia aenean -138206748,mauris enim -786076593,quis justo maecenas -709069825,pretium iaculis justo -165499559,sit amet diam in magna -858297918,sollicitudin -349912331,consequat dui -185803940,in faucibus -351552569,mauris -890868044,nisi at -468456256,maecenas pulvinar lobortis est -296053886,aliquet pulvinar sed nisl -505628176,sit amet sem fusce -357240360,amet lobortis -669270330,eros vestibulum -627561048,amet sem -691329172,ac leo -607834731,porta volutpat -379772046,vehicula consequat morbi a -669161127,est et tempus semper est -302507337,augue a suscipit nulla elit -704733219,ipsum praesent blandit -724713862,nunc -170190787,est phasellus sit amet -614821876,pellentesque at nulla suspendisse potenti -369670549,platea dictumst etiam -192395197,id turpis integer -396344915,elementum in hac -694705447,a feugiat -755783423,varius integer ac leo pellentesque -266129758,ac nibh -282041371,felis ut at -453096175,convallis -954478320,vestibulum -435226979,imperdiet -976594756,pulvinar lobortis est phasellus -380437660,justo in hac habitasse platea -993409868,rhoncus dui vel sem sed -369188325,aliquet pulvinar sed nisl -748909732,curabitur -125825993,nam ultrices -776212991,varius nulla facilisi cras non -556611018,praesent -184360691,lectus -583229015,felis fusce posuere felis sed -181545529,massa volutpat convallis -134687031,mauris viverra diam -512903717,in tempus sit amet sem -325743504,ac lobortis vel dapibus -736006381,posuere cubilia -570464899,eget elit sodales scelerisque mauris -468568497,fusce consequat nulla nisl nunc -965883487,tortor duis -206188327,sollicitudin vitae consectetuer eget rutrum -305275699,faucibus orci luctus -602737787,diam -164923967,et ultrices posuere -256189137,sed ante -917002398,convallis -745466607,dolor sit amet consectetuer adipiscing -657171842,ipsum aliquam -477955886,risus auctor sed -404190502,primis -767303726,malesuada in -587090739,aliquam quis turpis -309986793,leo rhoncus sed -399050729,aliquam augue quam sollicitudin vitae -648978100,et ultrices posuere -442879756,quisque porta volutpat erat quisque -922378639,scelerisque quam -144448711,consequat morbi a ipsum integer -675381657,sed nisl nunc rhoncus -198896494,in -628322687,nulla ut erat -736054383,donec vitae nisi nam ultrices -169897245,rutrum ac lobortis vel dapibus -897625560,sodales scelerisque -263899509,vulputate justo in blandit -419118376,magna bibendum imperdiet nullam orci -915366358,dapibus -588766979,diam vitae -800938774,donec vitae -281120194,habitasse platea dictumst etiam faucibus -872246043,praesent id -145423047,est et tempus semper est -507297147,sed tristique in -496716339,donec ut -230483541,venenatis lacinia -658422029,lorem ipsum dolor -296068475,consequat nulla nisl nunc nisl -271919037,volutpat dui -108262231,sit -475954757,interdum mauris ullamcorper purus sit -135311313,ac tellus semper interdum mauris -343026762,accumsan -131047362,lorem ipsum dolor sit amet -771280317,condimentum neque sapien -798195614,ante ipsum primis -124817241,amet eros suspendisse accumsan tortor -979155815,quam -425172206,lacus -737977433,ultrices erat -547540016,sem mauris laoreet ut rhoncus -486637355,orci -994830646,venenatis lacinia aenean sit amet -751431173,tristique -436412620,sed -967656705,diam -715900380,nulla ultrices aliquet maecenas -730501787,nec molestie sed justo -143693383,ut tellus -337526105,vivamus vestibulum sagittis -831805022,sapien arcu sed augue -947169097,aliquam quis turpis eget elit -921836696,mattis odio donec vitae -853413080,mollis molestie lorem quisque -638913015,ultrices aliquet maecenas leo -339213407,curae mauris viverra diam -291602911,euismod scelerisque quam -707465793,nunc nisl -112662158,magnis dis parturient -844604935,at diam nam tristique tortor -248424248,vestibulum ante ipsum primis -411043536,penatibus et magnis dis -781755680,urna pretium nisl -832661173,tincidunt lacus at -128841615,pellentesque -851975480,sapien a -846539799,sem duis aliquam convallis nunc -510086459,suspendisse potenti -850021803,turpis -549129417,sed vel enim -237272507,sed accumsan felis ut -474563882,odio -603888669,vulputate elementum -475656429,lorem id ligula suspendisse ornare -352536171,vivamus tortor duis mattis egestas -373688421,blandit -880618827,consectetuer adipiscing elit proin risus -636967255,quam sapien varius ut blandit -246749901,neque -890042734,quis odio -508869749,porta volutpat erat quisque -718104750,vivamus vestibulum sagittis sapien cum -199550845,vel dapibus at diam nam -515596940,eu orci mauris lacinia sapien -703327741,tristique fusce congue diam -584640254,ac neque duis -407190883,diam cras pellentesque volutpat dui -207084186,natoque penatibus -911323805,blandit -948103707,mattis egestas metus aenean fermentum -907292126,sollicitudin vitae consectetuer -632678805,nulla facilisi cras -862534471,mi sit -309197772,justo -379559602,dictumst -963081668,velit vivamus -711417861,est lacinia -245662368,nonummy maecenas tincidunt -398170170,eu nibh -200396687,sed vestibulum sit amet cursus -217297407,integer a -145949403,vel ipsum praesent blandit -743530646,amet eros -835695698,rutrum at lorem integer tincidunt -536922429,lectus pellentesque at nulla suspendisse -623210908,posuere cubilia -550701246,justo -365011965,massa -868540829,sapien -252549502,proin interdum -182899735,magna bibendum imperdiet nullam orci -150506021,nunc purus -284603862,luctus cum sociis -240551843,in eleifend quam a odio -153296157,semper est quam pharetra magna -516680848,non -291736648,lectus pellentesque eget nunc -319363211,vulputate elementum -133277581,lorem quisque ut -589456840,nisl ut volutpat sapien -216705591,vitae quam suspendisse -564449735,mus vivamus -552096339,eget massa tempor convallis -893474124,phasellus sit amet -213571319,ultrices aliquet maecenas -862007420,non ligula pellentesque ultrices phasellus -950178972,sagittis -871056166,consequat lectus in est -238762171,morbi non -842637862,amet sapien dignissim vestibulum -899556065,arcu libero rutrum -354652605,feugiat et eros vestibulum ac -993915051,dolor -538809859,pellentesque eget -518276529,ut volutpat sapien arcu -319272674,diam nam tristique tortor -480030234,cum sociis natoque penatibus -920826440,ut massa quis -192218862,porta -437708839,ut rhoncus aliquet pulvinar sed -697605676,ac est lacinia nisi venenatis -868421140,dolor vel est donec -357056343,id lobortis convallis tortor risus -243680682,morbi sem mauris -643646656,pede -939595619,enim blandit mi in porttitor -905693172,condimentum curabitur in libero -658790197,nisl nunc -106016265,convallis duis -184454471,morbi quis -208302366,semper rutrum nulla nunc -525489894,suspendisse potenti nullam -594503211,quam a odio in hac -931371316,ante vel ipsum praesent blandit -491945957,ultrices -794624370,nam dui proin leo -883947009,vivamus tortor duis mattis -471720602,sed interdum venenatis -728797603,tristique est et tempus -175548426,est quam -103774823,sed lacus morbi sem -811467682,fusce congue -981276161,aenean auctor gravida -858061579,donec semper sapien -167159659,blandit nam nulla integer -720745731,augue vestibulum ante ipsum -512285791,imperdiet et commodo vulputate -325756155,justo lacinia eget -940321946,viverra eget congue eget semper -587331559,nam -149325593,in porttitor pede justo -120375336,ac nibh fusce lacus -656512863,orci luctus -929972563,suspendisse potenti in -178070559,integer non velit donec diam -283938750,nullam -269311071,ac lobortis vel dapibus -308843929,tincidunt lacus at velit -615128372,curae nulla dapibus dolor vel -885831701,accumsan felis ut -902586593,et tempus semper est -851166627,leo -736218337,lacus -664904802,lorem quisque ut -845026820,odio donec vitae nisi -479533711,auctor gravida -702927461,cursus urna ut tellus nulla -848234633,nulla -531868298,integer ac neque duis -170269313,ut mauris eget massa -510369970,nulla -888339626,justo -350370900,sed sagittis nam -583286533,velit -755579909,nascetur -255055253,lorem id -791634480,non velit -258278979,quam pede lobortis ligula -267498007,etiam -988202308,nisl nunc nisl duis -847408605,curabitur in libero ut massa -187187284,mauris vulputate -625326635,porta volutpat -545287021,magna at nunc commodo -977057463,cum sociis natoque -400217255,lectus in est risus auctor -259939022,eget -601145256,congue elementum -358004828,quis -515708398,eu interdum eu tincidunt in -482966719,eu tincidunt in -358548147,hac habitasse platea dictumst -612848518,justo -492630640,nisl duis ac nibh fusce -699997035,pede venenatis non sodales sed -539783860,ridiculus -847174250,sed interdum -228048651,habitasse platea -781757847,integer aliquet massa -966715330,ultrices posuere cubilia curae donec -444583617,sapien a libero nam dui -659773773,eget semper rutrum nulla nunc -597783461,euismod scelerisque -176765081,ultrices -253761566,ligula in lacus curabitur -916396109,at lorem integer -748681223,morbi sem mauris laoreet ut -252287678,dolor quis odio -122756100,elit sodales scelerisque mauris -541531656,iaculis congue vivamus metus -466902591,vivamus tortor duis mattis egestas -347511404,amet lobortis sapien sapien -591596293,eget nunc donec quis orci -715066232,duis consequat -767485095,a suscipit nulla -246042942,aliquam augue -131288753,diam nam tristique tortor eu -234604099,blandit lacinia erat -527606983,convallis eget eleifend -407444384,pede venenatis -612860978,vitae nisi -825142562,morbi non -431749288,pellentesque eget nunc donec quis -749983908,purus -796755814,imperdiet et commodo vulputate -210706861,maecenas rhoncus aliquam lacus morbi -848828525,erat volutpat in -476393735,magna vestibulum aliquet -531603788,id ornare -313154695,cubilia curae nulla -797898062,quam sollicitudin vitae -439683082,sodales scelerisque -641630784,quis augue -645789107,morbi -349927202,consectetuer adipiscing elit proin interdum -352185561,duis mattis egestas metus -673279733,posuere cubilia curae nulla dapibus -946076195,turpis -748448195,etiam faucibus cursus urna -497954701,rutrum at -458450767,semper sapien a libero nam -954869034,nibh -297688430,ultrices vel augue -556747157,risus dapibus augue vel -453622843,lacinia aenean sit amet -334969731,sagittis nam congue risus semper -471937771,orci mauris -221171991,venenatis non -824243020,pellentesque ultrices -287554406,lectus aliquam sit amet diam -201098410,condimentum id luctus nec -795833485,in hac habitasse platea -177524743,arcu -254369634,nisi nam ultrices libero -224491329,erat volutpat -177584590,ipsum integer -722027283,mattis egestas metus aenean -750614861,duis faucibus accumsan odio curabitur -196586447,ac consequat metus -728682221,dolor quis -377113749,venenatis turpis -822503087,donec quis orci eget -243227074,duis -235292106,curabitur gravida nisi -134108108,nullam porttitor lacus at turpis -164871772,in faucibus orci luctus et -509504069,semper est -549472118,nulla tellus in -519461091,luctus et ultrices -706641464,vestibulum ante -219489765,id -794294762,eleifend -137046669,rhoncus aliquet pulvinar sed -718270035,massa donec dapibus duis at -587855515,id ligula suspendisse ornare consequat -850038490,consequat morbi a ipsum -868222400,ut -982483230,sagittis dui vel nisl -704276834,erat vestibulum sed -580661189,nibh -165797285,id ornare imperdiet -720616636,blandit non interdum in -239063036,duis bibendum morbi -352022128,elit ac nulla sed -499913784,morbi vel lectus in quam -410241119,bibendum morbi non quam -689437425,elementum eu interdum eu -402784511,turpis -167605704,vel ipsum praesent blandit -497814777,morbi vel -416054374,velit nec -913376580,id -397714802,et ultrices posuere cubilia -394539777,felis -555276541,eget eros elementum pellentesque -204117150,mauris ullamcorper purus sit -352588933,orci -279186791,magna bibendum imperdiet -415247673,ultrices posuere cubilia curae donec -953994803,non interdum -773081406,in -230586839,nulla -795624202,sapien non mi -519310952,est et tempus semper est -642130979,congue diam id ornare -809459966,tempus semper est quam pharetra -884419267,ligula nec -706183295,neque duis bibendum morbi -630687959,elementum nullam -409151137,aliquam lacus morbi -661560782,dolor sit amet -106518586,sed tincidunt eu felis -275014966,suspendisse ornare consequat lectus in -474962443,ultrices enim -469360885,leo rhoncus sed vestibulum -548460597,metus sapien ut -512046938,mauris non ligula pellentesque ultrices -391338656,nisl duis -762426820,vitae nisi -429446428,erat quisque -723277501,molestie hendrerit at vulputate vitae -786263505,pretium iaculis -694789590,vitae consectetuer eget rutrum -220327593,elementum pellentesque quisque porta volutpat -732852033,in faucibus orci luctus et -848030096,ultricies -671155381,libero non mattis pulvinar nulla -650888489,pellentesque -555017354,est et -208929735,condimentum -341449105,justo lacinia eget tincidunt eget -846130756,sapien placerat ante -144118109,nam -469779531,tristique -879532218,rutrum neque aenean auctor gravida -232955552,ipsum -494407325,tortor -223038781,venenatis turpis enim -142691688,placerat praesent blandit -269814248,fermentum justo nec condimentum neque -911761226,in -945144728,ut nunc vestibulum -678242330,luctus tincidunt nulla mollis -227780034,eu mi nulla ac enim -472200320,in quis justo -243447617,vulputate vitae nisl aenean lectus -654543326,metus vitae ipsum -524369942,lectus in quam fringilla rhoncus -620357760,at -849364864,tincidunt nulla mollis molestie lorem -438955842,tortor -935922422,proin -968345890,porttitor id consequat in consequat -681263448,orci nullam -647706499,donec -582583532,ac nibh -451098064,nunc rhoncus dui -140038221,dui -803259602,neque vestibulum eget vulputate ut -482928220,proin interdum -454070711,felis eu sapien -747087478,porta volutpat erat quisque -869942719,nulla pede -776971849,mauris lacinia sapien quis libero -945665008,proin leo -806482836,nunc commodo placerat -102026999,lorem quisque ut erat -675051316,pharetra magna vestibulum -920274615,libero rutrum ac -278407432,ut rhoncus aliquet -292979481,vel dapibus -305936411,tristique fusce congue diam -738560225,pede ac diam cras -679174587,platea dictumst aliquam augue -639057698,non -661873161,facilisi cras non -648291772,nibh -995393394,amet -432198435,auctor sed -320887910,dolor vel est -208574967,quam a odio in hac -147155644,urna -572873678,amet consectetuer adipiscing elit proin -365054337,lectus pellentesque eget nunc donec -864757042,sem sed sagittis nam -353172403,sapien sapien non mi -259996086,aenean auctor gravida sem praesent -311977708,aliquet pulvinar sed nisl -440985520,et tempus semper est quam -146715175,massa id -143942953,duis consequat dui -859652713,posuere metus vitae ipsum aliquam -543475350,in -121305555,convallis nunc proin at turpis -352183588,convallis -371665988,dui -867548323,vel augue vestibulum -223420036,non lectus aliquam sit -725093581,diam erat fermentum -306320548,ultrices aliquet maecenas leo odio -596296326,posuere metus -959828199,nibh ligula nec -998930225,lacinia eget tincidunt eget tempus -280897496,tellus nulla ut -177011733,montes nascetur ridiculus -389817703,ultrices libero non -607561285,platea -217999838,at -989889037,nulla -734270728,neque libero convallis eget -399509139,nec -577981284,lacus purus aliquet -217798278,curabitur gravida nisi -450043124,interdum venenatis -851741069,interdum -564753486,consectetuer adipiscing elit proin risus -945469431,elit proin risus -444834540,velit nec nisi vulputate -197081264,donec diam neque vestibulum -315898087,duis bibendum felis sed -543889115,in hac habitasse platea -948800779,lectus aliquam sit amet -799881740,duis faucibus accumsan odio -174276787,pellentesque ultrices phasellus id -367323572,ipsum -572219457,hac habitasse -673858874,urna ut -157581796,auctor sed -421753446,quam sollicitudin vitae -525688064,lacinia aenean sit -316529097,sapien in sapien iaculis congue -877379895,cras mi pede -631989180,massa donec -403710560,magnis -248641831,non pretium quis lectus suspendisse -978693665,elementum -936670195,porttitor lorem id ligula suspendisse -654418763,vel augue -360416434,ultrices libero non mattis -556296372,augue -402033145,orci pede venenatis non sodales -308671800,in hac habitasse platea -443705161,duis bibendum -807435473,aenean lectus pellentesque eget -681525201,augue aliquam erat volutpat -715632241,volutpat eleifend -651559208,amet -858447586,est risus auctor -991845856,felis eu sapien cursus -811976700,diam neque vestibulum eget vulputate -198427230,magna vestibulum aliquet -333567640,nam dui proin leo -310823806,enim -118694803,quis orci -260016296,vitae consectetuer eget -581461840,maecenas rhoncus aliquam lacus -690403575,sit -894102083,justo -234310294,integer -219171053,porttitor lorem id ligula -485465718,id consequat in consequat ut -991465158,duis at -937312081,sociis natoque penatibus et magnis -717544432,at velit eu -306909041,vivamus in felis -929774842,posuere cubilia curae -617173026,cubilia -764763438,lorem vitae mattis -426337166,sed justo -153269092,urna pretium nisl ut volutpat -352657150,purus aliquet at -132596728,convallis tortor -132109212,primis in faucibus orci luctus -703085592,in -162193851,mauris non ligula pellentesque ultrices -185568289,lectus -847285408,ac neque duis bibendum morbi -937929124,semper rutrum nulla nunc -454637516,cubilia -812501371,convallis -178266942,sodales -710199111,mi pede malesuada in imperdiet -430247775,interdum mauris non ligula -763322166,sollicitudin ut suscipit a feugiat -847172426,id sapien in -737102121,iaculis congue vivamus metus -774894017,a libero -242039544,integer ac leo pellentesque ultrices -119986953,nec nisi volutpat -859041228,augue vel -220122894,posuere cubilia curae mauris -547706480,ac leo pellentesque ultrices mattis -819502196,pretium quis lectus suspendisse potenti -980662117,nulla integer -602490699,purus sit amet nulla -943110249,sollicitudin ut suscipit -605639812,aliquet -696968907,massa quis augue -531634471,sem fusce consequat nulla -107383623,quam suspendisse potenti nullam porttitor -723083126,cubilia -239357128,amet justo morbi ut odio -802757895,sollicitudin mi -235083963,aliquam quis turpis -689911349,tincidunt eu felis fusce posuere -241152903,vulputate -229749732,in -685597771,gravida nisi at nibh in -625541052,aliquet -615402923,orci luctus et ultrices posuere -358263557,cras non -332734361,eleifend -838446721,duis bibendum felis sed -906355136,lacus morbi sem mauris -888753943,tempus vel pede morbi -540126476,viverra pede -292415195,enim blandit mi in porttitor -590755424,nulla mollis molestie -991672765,nisl aenean lectus pellentesque eget -378652733,maecenas pulvinar lobortis est phasellus -392468729,mi nulla ac enim in -242354526,vestibulum vestibulum ante ipsum primis -501406158,rhoncus dui vel -425818213,ligula -971142121,nulla suspendisse -831647499,vulputate vitae -890702490,nonummy maecenas tincidunt lacus at -321894129,vestibulum velit id pretium -176244709,ligula in lacus curabitur -381460092,lectus pellentesque eget -693222820,in quam -401804863,at vulputate vitae nisl -204356806,pede ullamcorper augue a -135416016,pede ullamcorper -351816779,velit nec nisi -633105880,augue vestibulum ante -614521855,donec ut -299547308,luctus et ultrices -715244248,non lectus aliquam -876957092,proin risus praesent lectus -762001546,condimentum id -897501178,eget orci vehicula condimentum curabitur -537772932,vestibulum -193853604,justo lacinia eget tincidunt -503413599,fringilla -311945080,mi -127160756,proin leo odio porttitor -345498111,ac neque duis -573758988,augue -504605398,tellus nisi -275910742,suscipit ligula in lacus curabitur -975497180,quisque porta volutpat erat -589349112,montes nascetur ridiculus mus -455547045,fermentum justo -528044689,lacus morbi -905016323,vestibulum ante -823741948,in ante -965271139,platea dictumst morbi -528537003,nascetur ridiculus mus vivamus vestibulum -235688190,aenean sit amet justo -991471855,suscipit -577161511,lacus morbi quis -674910358,nisi vulputate -762842613,donec -244339400,integer tincidunt -933549080,vel est donec -537284236,amet diam in -543538722,mauris eget massa tempor -368237656,eros suspendisse -984741269,sed -766632172,porta volutpat erat quisque -581807675,elit ac nulla sed -184019883,sapien ut nunc -973710743,ut erat curabitur gravida -611365928,vel est donec odio -273537642,cubilia curae nulla dapibus dolor -226185718,rhoncus dui -740378159,libero quis orci -617501583,urna pretium nisl ut -410057700,velit -289241131,volutpat sapien arcu sed -712559643,eget tincidunt eget tempus vel -956199971,nulla -389179163,vel dapibus -437441887,ultrices -352965577,suscipit ligula in lacus -443125619,sit -597043305,a -524053127,nullam -834398412,tortor sollicitudin mi sit -914898318,imperdiet sapien urna pretium nisl -743626608,morbi ut odio -132839740,quis augue luctus -116601853,primis in faucibus -130562754,ipsum praesent blandit -829754411,sem duis -703213639,aliquet pulvinar -412782655,nulla quisque arcu -853333815,molestie sed -340605464,ultrices erat tortor sollicitudin mi -914549449,suspendisse -754118662,eget congue eget -753568288,eleifend -946146650,viverra -634637566,amet eros suspendisse accumsan tortor -618182186,ut -634463659,nulla eget eros elementum -949010778,nunc nisl duis bibendum -954295046,semper interdum mauris -171929350,nulla tellus in sagittis dui -373132928,ut odio cras -223491931,placerat -611299793,sapien iaculis congue vivamus metus -849280132,hac habitasse platea dictumst -693747847,non quam nec -962378819,natoque penatibus et -184758243,cubilia curae mauris viverra diam -551484377,pede lobortis ligula -701332469,laoreet ut rhoncus aliquet -585191934,tempus vivamus -305833408,ut massa quis augue -903293830,blandit ultrices enim lorem ipsum -954785560,ac consequat metus sapien ut -564109111,eu -181036534,lacus morbi -657563230,non mi integer -763926710,phasellus id -710816166,proin risus praesent lectus vestibulum -960383490,consequat nulla -154170665,consequat -553050470,id ornare imperdiet -994234057,pede morbi -816764175,enim leo rhoncus -529396545,leo rhoncus -324737296,consequat dui nec nisi volutpat -727196129,sit amet consectetuer adipiscing elit -756095827,maecenas tincidunt lacus at velit -633151238,nam tristique tortor -137382009,lacus purus aliquet at -436989376,cubilia curae mauris viverra -948999999,dui vel sem -833957026,tincidunt nulla mollis molestie -111596599,morbi -407353950,pede venenatis -412479759,est lacinia nisi -711408430,pellentesque ultrices -530962538,adipiscing elit proin -713782005,penatibus et magnis dis parturient -502962681,sed interdum venenatis turpis -544698124,vel nulla eget eros -191749614,pellentesque -710113489,in sapien iaculis -732505236,nulla ac enim -463509171,vel nisl -589527820,odio curabitur -521809280,mi sit -371798266,amet eleifend pede -942749441,justo -797012591,quisque -964141090,eget orci vehicula condimentum -834658448,scelerisque quam turpis adipiscing lorem -893830638,fermentum donec -632649353,iaculis congue vivamus metus -476890595,semper rutrum nulla nunc -645842468,rutrum rutrum neque aenean -300302956,nec -517630393,tincidunt nulla mollis molestie -101317989,massa volutpat convallis morbi odio -304256512,erat quisque -794138109,mauris -569293681,phasellus id sapien -109026956,est donec odio justo sollicitudin -394546277,vulputate -899442728,id luctus nec molestie sed -430343074,leo odio condimentum -838309015,lobortis convallis tortor risus dapibus -315649458,augue vestibulum rutrum rutrum neque -735671626,volutpat erat quisque erat eros -651165984,imperdiet et commodo vulputate -603626513,luctus et -239715338,vel pede -105939398,sollicitudin vitae consectetuer -487097889,ut rhoncus -575716982,posuere nonummy integer non velit -166653212,nibh ligula nec sem -987702229,vel pede morbi porttitor lorem -276108505,lobortis vel dapibus at -979891024,ac diam cras pellentesque -210101902,pede ac diam cras pellentesque -605051395,id ornare imperdiet -977695134,fermentum donec ut mauris -921630123,ligula -678493478,felis sed lacus -526030901,quam -749470020,non pretium quis lectus -219095768,faucibus orci luctus et -133470047,lobortis est -121750134,ipsum aliquam -201931151,lacinia -359769219,venenatis non sodales sed -657177350,consequat metus sapien -836776132,consequat varius integer ac leo -321764221,volutpat eleifend donec ut dolor -622997751,non -509330752,tortor eu -275075215,cursus urna ut tellus -416528875,lectus in est -481320928,orci luctus et ultrices -993320703,elementum nullam varius nulla facilisi -183971024,molestie -783608645,phasellus sit amet -642655683,eros suspendisse accumsan tortor -282686500,suspendisse accumsan tortor -989025596,luctus et ultrices -148529718,iaculis congue vivamus metus -521988850,ut odio cras mi pede -845830283,ac lobortis vel -826222377,etiam justo etiam pretium iaculis -495423598,in sapien iaculis congue -607752435,non mauris morbi -639261863,justo sollicitudin ut -489661093,ante vel -747163655,ut massa volutpat -980677475,justo etiam pretium iaculis -451960232,massa tempor convallis -158929204,mauris sit amet eros -204505339,sit -866118130,est -315055175,in consequat ut nulla sed -784815367,dis -904542972,pretium quis lectus -355647622,at nibh -338864838,interdum venenatis turpis enim blandit -740277466,lorem ipsum dolor sit amet -530471309,molestie sed justo -931029872,maecenas rhoncus aliquam lacus morbi -670692894,pede libero quis orci nullam -452515782,lobortis sapien -582801985,ultrices posuere cubilia curae nulla -122146246,venenatis tristique fusce congue -628002638,quam pharetra -599063197,elit proin interdum -259608013,faucibus orci luctus -703532637,elit ac -479147929,nec -439916918,magna ac consequat -143017621,nisl duis ac nibh fusce -161791666,imperdiet sapien urna -562744270,justo aliquam quis -876716825,congue diam id -924085113,odio -936080390,neque sapien placerat ante -379155179,diam -750265554,id -876830641,luctus nec -288649093,massa donec dapibus -643249965,at velit vivamus -311412897,in -878129677,tincidunt -125368371,diam id ornare -351088560,cras in -722222408,cras in purus eu -382506014,erat quisque erat eros viverra -701194888,sit amet -585808893,nam tristique tortor eu -349664866,tortor risus dapibus augue -936900732,felis sed -280888280,pretium -909782854,nulla suscipit ligula in -139178703,tellus in -239500463,erat curabitur gravida -684290898,congue etiam justo etiam -384059791,dis parturient -766029536,cum sociis natoque penatibus -330006642,donec vitae -413892940,dui -209346666,mauris viverra diam -997536391,sollicitudin ut suscipit a -275522183,volutpat eleifend donec ut -575169684,in hac habitasse platea -300969120,ac est lacinia -455540915,vulputate -593914051,maecenas tincidunt lacus at velit -234905973,ipsum integer -776164614,id pretium iaculis diam erat -815294564,quisque erat eros viverra -543226130,nam nulla -303668099,in sagittis dui vel nisl -855405016,amet -993523553,aliquam sit amet -447572188,diam -199358893,rhoncus mauris -962059419,consequat dui nec -689704466,sed interdum venenatis turpis -999435981,ut suscipit a feugiat -759049632,consequat -669373077,pulvinar -653421947,in libero ut massa volutpat -942454503,dui -558063602,rutrum rutrum neque -867057464,erat id mauris vulputate elementum -934321811,ipsum dolor sit -185398049,mauris non ligula -214091997,quis odio -728557205,nisl aenean lectus -525955638,sed vel enim sit -296688048,eget massa tempor convallis nulla -942606468,tempus vivamus in -724035049,dui -821688502,diam neque vestibulum eget vulputate -601769208,in lectus pellentesque -437744744,aenean lectus pellentesque eget -355898634,habitasse platea -833871248,cubilia curae -143065498,aliquam convallis nunc -965448496,vulputate ut ultrices vel -634407703,nulla justo -765077169,sit amet consectetuer adipiscing -193771267,vel est -529465104,fusce congue diam id ornare -981846867,vulputate -642879374,in -402257363,sit amet diam in -704502084,amet consectetuer adipiscing elit -188794937,in blandit ultrices enim lorem -253727194,porttitor pede justo eu -949283402,nulla quisque arcu -842397359,ipsum -208680218,sed tincidunt eu felis -261480152,ac -126368770,tellus nisi eu orci -104116054,augue vestibulum ante -397399858,mauris viverra -515094063,morbi odio odio elementum -139084844,molestie hendrerit at -442855561,parturient montes nascetur ridiculus -711109831,ut suscipit a feugiat et -863058890,amet nunc viverra dapibus nulla -836189272,in blandit ultrices -321840192,congue -607641852,tristique in tempus sit -665625675,justo aliquam quis turpis -734890564,eu orci -644186070,in leo maecenas pulvinar -445503616,nec dui luctus rutrum nulla -693912319,ut -942141728,in faucibus orci luctus et -339991605,cras non velit nec nisi -356509000,id -392846181,in -323925191,cum sociis natoque penatibus et -666190885,gravida nisi at nibh -733561251,phasellus sit amet erat nulla -740503390,quis -326274459,amet diam in magna -322162186,nulla ac enim in -214623585,consequat in consequat ut -693519960,quis turpis sed ante -729627931,justo -776353697,blandit lacinia erat -165993791,mi nulla ac enim -555781752,turpis nec euismod scelerisque -786159396,nulla eget eros elementum pellentesque -464676487,nulla sed vel enim sit -865039801,molestie hendrerit -482091462,mollis molestie lorem quisque ut -834636989,ultrices vel augue vestibulum -633492320,id mauris vulputate elementum nullam -373444596,cras non velit -440412839,nisi eu orci -639178352,accumsan odio curabitur -965840126,eget -843113686,sit amet -558862457,volutpat -651780669,turpis enim -584986904,lacinia nisi -416450492,faucibus orci luctus et ultrices -236412894,vestibulum vestibulum ante ipsum -115513438,etiam -470562379,viverra dapibus nulla -740721361,nunc purus phasellus -604571994,primis in faucibus -477375029,at turpis -402452813,pellentesque quisque -739183020,in consequat ut nulla sed -147645112,maecenas rhoncus aliquam lacus -160973996,vulputate elementum nullam varius nulla -308321070,sapien varius -868967160,neque vestibulum eget vulputate ut -134601496,consequat in -928614946,sapien -789717644,sapien cum sociis natoque -457578470,vestibulum -297335979,eleifend quam a odio in -762984507,tincidunt lacus -298032057,ultrices phasellus id sapien in -675817323,eu pede -897062571,orci luctus et -485203484,praesent -654548091,mauris vulputate elementum nullam -158975879,aliquet maecenas leo -956845485,convallis -714113622,tempor -961785926,odio -360094535,posuere felis sed lacus morbi -691685749,purus eu -696945488,natoque penatibus et -974706952,pede malesuada in -421530156,fusce -375084508,luctus -434484272,dolor vel est -822543420,donec ut mauris eget massa -738463176,ipsum dolor -310302108,posuere metus -196221966,nulla ac enim -316973560,molestie nibh -748090218,sit amet diam in magna -629776238,lacinia aenean sit amet -302532938,lorem -622362084,luctus et ultrices -469864816,elit -385954840,ante nulla -509582536,amet -225237869,curabitur in -259021138,justo etiam pretium iaculis -143773217,proin -287933908,ut nunc vestibulum ante ipsum -580670701,platea -505669120,nisl aenean -339440691,sed magna at nunc -837616870,suspendisse ornare consequat lectus -176203849,tincidunt -770600393,sem -449215233,non mattis -133589664,enim -290885511,interdum eu tincidunt -462846300,libero rutrum ac lobortis vel -158887978,luctus ultricies eu nibh quisque -223634271,orci pede venenatis non sodales -708333306,orci -520872323,nam congue -845832193,lorem vitae mattis -643995347,at nunc commodo placerat praesent -523523030,sapien -737605641,tincidunt eget tempus vel pede -814409567,aenean lectus pellentesque eget nunc -465108690,aenean auctor gravida -992148905,ultrices vel -881385897,massa quis augue luctus tincidunt -787068989,lacus morbi quis -917804527,eros viverra -501327322,sit amet -481246481,tortor risus -739091559,purus -703608415,vitae ipsum aliquam non -988507201,id turpis integer aliquet -278943880,amet lobortis sapien sapien non -773985235,diam neque vestibulum eget vulputate -169530393,phasellus in felis donec semper -973687327,ac nibh fusce -468006404,integer -697967927,non mattis -605935041,nisl aenean -915045680,potenti nullam porttitor lacus at -503385422,ante vivamus tortor -751961321,dui vel nisl duis -751364657,praesent -326326766,dictumst -587939884,nulla elit ac -585307375,suscipit -424494038,eget congue -235535349,luctus -384863266,augue -871250096,sit amet -799995635,turpis enim blandit mi in -908840422,aliquam non mauris morbi non -255797413,eu sapien cursus vestibulum proin -471753226,non -656740320,fermentum justo nec condimentum neque -721253173,et magnis dis parturient montes -632284189,pulvinar lobortis est phasellus -261893457,turpis sed ante vivamus -398988194,vel lectus in -726230808,primis -433959376,rutrum neque -141607782,in congue etiam justo -357644010,ut suscipit a feugiat -886472729,sem praesent id -909139393,rhoncus aliquet pulvinar -593634245,ante vel -556387350,suspendisse ornare consequat -219929448,vestibulum ante ipsum primis in -255042847,massa tempor convallis -496526986,diam vitae quam suspendisse -901958085,sed -225212260,erat -206813911,ipsum primis in -203576446,sed augue aliquam erat volutpat -595836714,auctor sed tristique -876681517,orci luctus -277791044,parturient montes nascetur ridiculus mus -179995426,ligula in lacus curabitur -628919368,varius ut blandit non interdum -834701116,posuere nonummy integer non -541343955,donec ut -611764108,nisi venenatis tristique fusce congue -562820776,rutrum ac -878030323,cras -353309172,odio justo sollicitudin ut -495435822,rhoncus sed vestibulum -365023623,turpis eget -499781847,mauris lacinia sapien quis -936437895,sed tincidunt eu -340908384,id nisl venenatis lacinia aenean -287066561,risus dapibus augue -662783706,dui luctus rutrum nulla -513621584,lectus pellentesque at nulla -659752355,eros suspendisse -656865537,quis -224384195,odio porttitor id -361045527,augue -822994293,venenatis tristique -916500611,commodo vulputate -880407037,elementum pellentesque quisque porta volutpat -998152564,sapien arcu sed augue -894602820,placerat ante nulla justo -819790907,vitae mattis nibh ligula -847725799,ridiculus mus etiam -315211770,aenean auctor gravida sem praesent -553035008,purus sit amet nulla -678109008,orci luctus et ultrices posuere -893641220,quam nec -481022106,nulla -794419661,convallis morbi odio odio -699838832,dapibus at diam -307997916,est et tempus semper -118388327,diam in magna -324981561,rhoncus mauris enim leo rhoncus -745706500,turpis elementum ligula -400594948,leo odio condimentum -936888287,feugiat -635045557,sollicitudin ut suscipit a -898713277,fusce congue diam id -574174553,ante vivamus tortor duis mattis -528393961,curae donec pharetra magna -617989636,ante vel -531690166,in tempus sit -258556186,vel augue vestibulum ante ipsum -658344543,nulla pede ullamcorper augue -551672298,at velit eu -836480417,dapibus augue vel accumsan -249307351,sit amet sem -822349962,neque sapien -912538122,consequat nulla nisl nunc nisl -677525429,duis bibendum morbi non quam -719407001,ante nulla justo aliquam -893708601,elementum pellentesque -113805332,venenatis turpis enim blandit -850315804,ipsum -541354872,in sagittis -943934321,amet diam in magna -257182940,quisque id -563486184,eget -526630486,velit eu est congue -783066388,vestibulum eget vulputate ut ultrices -982205445,sit amet -965580981,ornare consequat -575118118,dui vel nisl duis ac -589022493,risus auctor -524198961,felis eu -619776379,pulvinar sed nisl nunc -213542586,potenti -302010657,auctor sed tristique -867197741,in sapien iaculis -778848393,platea dictumst maecenas ut massa -984488582,nulla mollis molestie lorem quisque -485395431,sit amet -139302358,in -287176682,ridiculus mus etiam -735398263,lacus morbi sem mauris -553862609,habitasse platea -412610428,vestibulum rutrum -796232367,nam nulla integer pede -755414344,nibh quisque id -291106401,scelerisque quam turpis adipiscing -868511644,turpis donec posuere -891837186,risus auctor sed tristique -846940150,donec quis orci eget -687180617,sit amet sapien dignissim vestibulum -504755069,sapien -881965694,ut odio cras -838470993,mauris enim -500074370,ante ipsum primis in -231789987,erat -880219548,vestibulum ante -275626803,ultrices -797188439,lectus pellentesque eget nunc donec -910002145,sit amet nulla quisque -700203298,sociis natoque penatibus -121337189,nisl duis ac nibh -286755244,quam pharetra magna ac -163578234,varius nulla facilisi -209519071,libero quis orci -864778715,ut nunc vestibulum -643394862,nibh in lectus pellentesque -814640370,non mauris morbi -576987359,tempus semper est -230463780,in -635180657,integer a -743509524,amet eros -529503333,ut erat curabitur -544114892,sagittis dui vel -493208734,maecenas ut massa quis augue -177826566,vestibulum -645236569,luctus et ultrices posuere cubilia -215329203,viverra dapibus nulla suscipit ligula -625470085,lacus at -735607807,diam id -649633152,vitae mattis nibh -567038333,pretium nisl ut -786683061,donec quis -177473982,quisque erat eros viverra -346409538,libero non mattis -861456823,bibendum imperdiet nullam orci pede -926872805,urna ut tellus nulla -380779240,mauris non -335708566,congue eget semper -174166781,integer non -667175399,luctus ultricies eu nibh quisque -860658934,luctus et ultrices posuere -793511120,blandit nam nulla -110756918,rutrum neque aenean -333466616,leo maecenas -352801292,blandit ultrices enim lorem ipsum -543361994,euismod scelerisque -651655173,aliquet maecenas leo odio -219283850,velit nec nisi vulputate -612249755,vitae -639813485,venenatis turpis -505525996,suspendisse -967081527,phasellus -866545111,adipiscing -504442252,tincidunt nulla mollis molestie lorem -419963477,tincidunt eu -683621882,erat quisque -504996457,lacus at velit vivamus -592857339,vivamus vel nulla -793905699,aliquam non mauris -630856630,vestibulum ante ipsum primis -664466066,eget nunc donec quis -330322182,nonummy integer non velit -895182283,commodo placerat praesent blandit nam -995552922,semper rutrum nulla nunc -582705515,mauris non ligula pellentesque -219910703,nam tristique tortor -709572128,cras pellentesque volutpat -949682689,integer ac -475339348,in -424750593,adipiscing elit proin -496978286,tempus semper est quam pharetra -929776339,cum sociis natoque penatibus et -793076602,erat quisque erat eros -277003288,aliquam convallis nunc proin at -102162928,est -288767568,vitae nisl -938335247,tempor convallis -187399097,nisl nunc -596123354,erat fermentum justo nec condimentum -733238321,sed -565988254,non -637765373,rutrum ac lobortis vel dapibus -454030692,diam cras -386347397,nulla ultrices aliquet maecenas -407610599,lorem quisque -312721934,purus aliquet at feugiat non -393091532,massa volutpat -307213036,ultrices vel augue -257441955,nullam orci pede venenatis -524944060,in faucibus orci luctus et -611531367,nulla tempus vivamus -541715763,ullamcorper augue a suscipit nulla -908593004,nibh -324051640,dictumst maecenas ut massa -195585114,aliquet -239250385,vulputate nonummy maecenas -659014365,platea -511075040,ipsum aliquam non mauris -480794668,gravida nisi at -376576351,varius integer ac -896875122,nulla nunc -957106064,rhoncus aliquam lacus -548433613,nibh in lectus pellentesque -399775909,sit amet sem fusce -603921339,lorem -450588374,tempus semper est -343971699,felis donec semper sapien -446427594,volutpat -276118198,vulputate -160584437,augue -532137099,semper est quam pharetra magna -576748481,nam tristique -204963593,dapibus dolor vel -153152306,neque duis bibendum morbi -530113846,nam ultrices libero -938561187,iaculis congue vivamus metus arcu -469452067,posuere cubilia curae nulla -861510225,imperdiet et commodo vulputate justo -692579944,accumsan felis ut -231521985,luctus -848846610,nulla dapibus dolor vel est -763420061,id sapien in -357218534,est congue -246771388,vulputate ut -845588522,mattis -611527050,ac -957769254,amet -593490355,a pede posuere nonummy integer -510359797,lorem id -609875593,eu mi -511206214,nulla -770352641,vel enim sit amet -541028077,dui vel sem sed sagittis -128205534,natoque penatibus et -466117018,odio justo sollicitudin -948184520,ultrices posuere cubilia curae nulla -681231848,et magnis dis parturient -646721861,at nulla -254007064,pulvinar nulla pede -513745986,eros elementum -154544316,posuere cubilia curae donec pharetra -198352252,non velit nec nisi -721507468,curae mauris viverra diam vitae -914172931,mauris morbi non lectus -336109172,sed lacus -345100393,venenatis non sodales -785285197,orci -723854623,tortor quis -943581789,libero -178113913,eget -350029011,ut rhoncus -959913645,semper interdum -558558235,non velit donec diam -709685880,odio -187266142,nibh quisque id -749942134,rutrum nulla tellus -603283312,condimentum curabitur in -168934693,et ultrices posuere -753223194,eget nunc -579190533,velit -536893640,curabitur at -523002900,lacus at velit vivamus vel -680330054,sed justo pellentesque -359006468,sagittis dui -524298041,donec semper -500278684,sed accumsan felis -514838959,blandit nam nulla -392775021,eu mi nulla -366109805,mauris lacinia sapien quis -324661404,ut -417393765,mauris enim leo -245489533,duis aliquam -812505247,sapien arcu sed -282780162,nulla sed -367044326,odio elementum eu interdum eu -522853879,id -226545438,potenti -759210438,donec quis orci eget -525666433,maecenas tincidunt lacus -365280529,tempus vivamus in -247359442,rutrum nulla -156384369,sapien ut nunc vestibulum -749847473,sociis natoque penatibus et -193856769,porta volutpat quam pede lobortis -915910904,pellentesque ultrices mattis odio -497545925,duis bibendum morbi non quam -414606663,libero -818679000,orci -850130804,sit amet -677613717,velit -233047954,interdum in ante vestibulum ante -478062712,est risus -359414429,at -793914145,commodo vulputate justo in blandit -801136346,fringilla -527664639,lorem integer tincidunt ante -836240766,pede justo eu massa -854339010,bibendum -528194564,vehicula -987613542,sodales scelerisque mauris sit -291277754,eu -110398131,sem -295161877,et tempus semper est quam -334649939,velit nec nisi vulputate nonummy -235385017,non lectus aliquam sit -835972332,id sapien in sapien iaculis -399864670,in -804782645,proin interdum mauris non ligula -693457001,diam erat -406301020,libero -623319073,suspendisse ornare consequat lectus in -459831955,blandit -630241179,mi sit amet -179476026,vel nisl duis ac -184414479,est donec odio justo -109481102,vestibulum -598700941,interdum -922019475,sit -956092836,curabitur at ipsum ac -948051771,natoque penatibus -253484815,integer a -367225470,nec nisi -555361421,sit amet cursus id turpis -889091574,at lorem -306755638,rutrum rutrum -276973331,semper -126979340,quam nec dui -844384096,quam -742491156,congue risus semper porta -229458983,ac diam -589827823,rutrum -878824049,massa quis augue -245912742,lacinia aenean -481802458,pharetra -963819324,at -508102968,convallis nunc -775666250,lorem ipsum dolor sit amet -440128473,dui maecenas -232836253,blandit -578544047,massa id -636471056,imperdiet nullam orci pede -503740730,orci -573183312,est donec odio justo sollicitudin -282856492,posuere felis -817287711,sed vestibulum sit amet -880689996,donec odio justo sollicitudin ut -698680024,nibh -972400306,pulvinar lobortis est phasellus -520845061,quis justo maecenas -724111332,porttitor lorem id ligula suspendisse -968029166,consectetuer adipiscing elit proin risus -878419231,sapien varius ut blandit -456866042,eu mi nulla ac enim -400390180,justo sollicitudin ut -972217778,ante ipsum primis in faucibus -608828129,lacinia -875588446,erat quisque erat -555547224,dolor -219282506,bibendum felis sed -797889375,orci mauris lacinia sapien quis -214482605,ut volutpat -511776277,primis in faucibus orci -857599371,lorem ipsum -766447881,et eros -565288435,at -354966546,congue risus semper -515906472,justo sit amet sapien dignissim -613662601,duis consequat dui -491165606,eget vulputate ut ultrices -891833425,felis fusce -943717581,donec -783429121,a -539540586,lobortis sapien sapien -703092804,dolor quis -232142846,vitae nisl aenean -382625836,vel augue vestibulum rutrum rutrum -965645077,pede -302224903,curabitur at ipsum -211153960,ridiculus mus etiam vel augue -649429860,duis ac -409889959,curabitur -624324842,cubilia curae mauris -640021337,suscipit nulla elit ac -494299823,condimentum neque sapien placerat -431137391,sodales scelerisque mauris sit amet -254394118,eros -415769370,proin leo odio -701891945,dapibus duis at -365706477,nibh in quis -842917963,nisi vulputate nonummy -423608809,luctus et ultrices posuere -464289351,integer aliquet massa -724104078,quis justo maecenas rhoncus aliquam -329346582,id massa id nisl -870292563,lorem ipsum dolor sit -576278695,lectus pellentesque -771950325,neque sapien -118470988,ante ipsum primis in faucibus -833126701,tortor duis mattis egestas -317335610,nunc vestibulum ante -425006350,porttitor pede justo eu -244218150,tellus semper interdum -374860462,interdum mauris non ligula pellentesque -468863478,vestibulum -371750828,mus vivamus vestibulum -472044552,a feugiat -617636417,primis -159435938,praesent blandit nam -923120376,elit sodales scelerisque mauris -714615890,cum sociis -797160741,pretium iaculis justo in hac -189232693,lacus at -903228486,donec pharetra magna vestibulum -331864099,sit amet lobortis sapien -700167465,quam nec dui luctus -908684192,posuere nonummy integer non velit -414020851,dictumst etiam faucibus cursus urna -479649133,sed tincidunt eu felis fusce -883527779,blandit nam -296230681,accumsan odio curabitur -270448200,faucibus orci luctus et ultrices -716854332,dictumst aliquam augue -798351181,leo -235582103,elit -857567774,erat -286899959,et -396989526,etiam vel augue -784419030,augue quam -924595756,at lorem integer tincidunt ante -745022344,ultrices -321528679,lorem vitae -307151629,sit amet -295217572,a -222846829,posuere -832433548,porttitor lacus -973357169,quam nec dui -522108930,interdum in ante -588994942,volutpat -947897626,bibendum felis sed -883821648,vestibulum ante ipsum primis -313886956,quam pede lobortis ligula -979776841,suspendisse -613893949,sit amet nulla quisque -823437836,turpis -583394963,in magna -386989475,congue vivamus metus -831945573,odio cras -782637053,molestie hendrerit -228174478,convallis duis consequat dui nec -164959785,in -224779839,ligula sit -420894991,arcu sed augue aliquam erat -322756853,justo -745256910,et ultrices posuere cubilia curae -985512010,gravida nisi at nibh -139507704,sed vel enim sit amet -376732697,sed sagittis nam -494509559,at velit eu est congue -529196277,aliquam augue quam -256642891,ut nunc vestibulum -739356043,semper interdum mauris -704153087,convallis morbi -990556363,rhoncus dui vel sem -942272399,gravida sem praesent id massa -934866853,nibh in hac habitasse -677070145,nullam -301764825,ultrices erat tortor -252798120,eget tincidunt eget tempus -205313991,donec -865277484,luctus tincidunt nulla -170450541,pellentesque eget nunc donec quis -167708664,mi integer ac neque -511780808,id -936071279,felis fusce -912929182,proin leo odio -990990253,pellentesque ultrices mattis odio donec -119504671,sagittis sapien cum sociis -896930856,at lorem -983079513,placerat praesent blandit nam nulla -112527653,a pede posuere -634436068,pede justo lacinia -662966946,id lobortis convallis tortor -605319248,odio porttitor id consequat -267217262,nulla dapibus dolor -205014280,pharetra -244715598,in imperdiet -959592703,elementum ligula vehicula consequat -896347971,at diam nam tristique -957802237,consequat metus sapien -351897223,tincidunt nulla mollis -899427399,accumsan -381813901,magna vestibulum aliquet ultrices -670013231,praesent lectus vestibulum -701729063,elementum nullam varius nulla facilisi -859561193,vel sem sed -467244921,purus sit amet nulla quisque -464395926,enim -534606767,ridiculus mus -430638492,nisl venenatis lacinia aenean -258944251,eget tincidunt eget -856586222,turpis eget elit sodales -688430896,ipsum -221587404,pretium nisl -598180297,sit amet justo morbi ut -841815350,in tempus sit amet sem -778823902,quis lectus suspendisse -590653251,sed interdum venenatis turpis -451413707,ut -750860568,sagittis -241495728,erat fermentum justo -478953813,felis ut -541411617,venenatis tristique fusce congue -725628126,natoque -600459330,velit eu est -333478537,potenti nullam porttitor lacus -706942922,posuere cubilia -924813984,lobortis ligula sit amet eleifend -918533676,nam -841000057,ut blandit non interdum in -636379899,arcu -666242398,magnis -814397087,est et tempus semper -912473612,mauris -458423896,fusce consequat -254650724,porttitor lorem id -151732831,massa id nisl -381541466,cubilia curae mauris -800050617,cum sociis natoque -485469329,dapibus nulla suscipit ligula -357688950,maecenas -232431330,nam ultrices libero -864784029,ut volutpat sapien -800999750,vitae ipsum aliquam non -167453644,nullam -862330784,leo -998760412,eu tincidunt in leo maecenas -908490790,nunc -959542802,volutpat dui maecenas tristique -980154671,vulputate vitae nisl aenean -366354315,morbi non -349319528,metus sapien ut -593352914,platea dictumst maecenas ut -207608032,fringilla rhoncus mauris enim leo -324183381,amet sapien dignissim -198864229,sagittis dui vel -797089005,nibh ligula nec sem duis -982462741,vel -267717270,praesent id massa -631361864,nonummy integer non velit -131577688,non sodales sed tincidunt eu -920904361,consequat -544903299,sapien arcu sed -786574738,turpis adipiscing lorem vitae -183807765,rutrum rutrum neque -921632317,aliquet -289156412,sit amet -116271582,augue aliquam -230463782,augue aliquam erat volutpat in -925673307,id massa id -315921800,ipsum dolor -420933792,dui nec -947487520,malesuada in imperdiet et commodo -596050702,rhoncus sed -260220835,quam a -667563993,neque duis bibendum morbi -186183503,leo odio condimentum -241627727,lobortis ligula sit amet eleifend -608096736,ante ipsum primis in faucibus -375300920,suscipit -699037049,accumsan odio curabitur convallis -760393771,cras non velit nec -818082141,venenatis non sodales -932607894,purus sit amet -299088466,diam neque vestibulum eget -826095553,sit amet lobortis -791144943,a ipsum -886945807,tincidunt eu -631174539,nunc -602652358,a feugiat et eros -403512649,amet turpis elementum ligula vehicula -681073226,lacinia aenean sit amet -437909951,elit proin interdum -535192111,massa tempor -741123647,quam sapien varius -978598398,est donec odio justo sollicitudin -391294330,a feugiat et eros vestibulum -824735317,eget vulputate ut ultrices -681701285,faucibus orci luctus -942731904,ipsum aliquam non mauris morbi -883455088,mattis odio donec vitae nisi -381514569,ultrices posuere cubilia -761322411,metus arcu adipiscing -201275246,et tempus -197301975,donec -419460620,consectetuer adipiscing elit proin risus -756378389,nulla suscipit ligula in -503574262,ligula suspendisse ornare consequat -999520025,posuere -602962256,maecenas leo odio -579779128,elit proin -997345142,vel -912982789,amet eleifend -743435926,mattis nibh -442789144,ut mauris eget massa -485910110,quis turpis sed ante -380792722,nascetur ridiculus -756350371,sed justo pellentesque viverra -792386488,aliquet massa id lobortis -675687785,vestibulum ante ipsum primis -659644748,faucibus orci luctus -532254757,curae nulla dapibus dolor -482720097,auctor sed tristique -687377967,amet nulla quisque -820292431,congue eget semper rutrum -811228403,sed tincidunt eu -261781444,metus arcu -945635449,etiam pretium iaculis justo -279405221,mauris non ligula -425078242,mus -623077925,primis in faucibus orci -893953387,imperdiet nullam orci pede venenatis -385136220,eros vestibulum ac est -404980916,nec molestie sed justo pellentesque -943334129,tincidunt in -459820309,consequat -721586657,lacus at turpis donec -328252657,tempus vivamus -718378834,risus semper porta volutpat quam -759288196,suscipit -905976986,ipsum -950883095,mattis -990670588,lectus -775733307,ornare imperdiet sapien urna -377981430,dictumst etiam -334848991,ullamcorper augue -636851062,consequat metus sapien -781964945,non quam nec -583515474,duis -956982256,metus aenean -172362988,pede -864814184,mi -657872456,id lobortis convallis -244444383,sit -573176712,ligula nec sem duis aliquam -244265320,morbi odio -149936021,tristique -529116611,ut dolor morbi vel lectus -327310872,a feugiat -995446032,nulla dapibus dolor vel est -371570109,justo sollicitudin ut -826149237,ac -851891257,integer non velit -772176434,quam sapien -457958811,ultricies eu -331685368,id ligula suspendisse -794041505,montes nascetur -963695854,duis -576267315,risus semper porta -212551622,eu -816759579,pellentesque quisque porta -190990916,at velit eu est congue -989212403,consequat dui nec nisi -609427515,volutpat convallis -785987981,vestibulum -380729737,nulla sed vel enim -666088786,sapien arcu sed augue aliquam -407204557,vel pede morbi porttitor -432253764,vestibulum sed magna at -193695964,dictumst aliquam -242355151,mauris morbi non lectus aliquam -722469565,natoque penatibus et -549931412,in hac habitasse platea -279202540,faucibus cursus urna ut -389207916,duis ac nibh fusce lacus -694895224,platea -430913947,congue diam id ornare -845847459,lectus pellentesque -946035945,convallis nunc proin -664802691,scelerisque mauris -815000738,nec condimentum neque sapien -952676238,faucibus orci luctus et ultrices -339957959,lorem vitae mattis -924958315,justo pellentesque viverra pede -409699032,maecenas ut massa -698353463,at lorem -927572196,turpis -785088497,fermentum donec ut mauris -176539041,interdum eu tincidunt in -397307346,porttitor lorem -572118294,amet -289811393,etiam justo etiam pretium -715371199,erat id mauris vulputate elementum -633145368,eros vestibulum ac -755782120,vel lectus -263188287,amet -510086775,felis eu sapien cursus -560016642,luctus et -578180579,tempus vel pede morbi porttitor -969269055,vel est -519699412,sem praesent id massa -560457812,elit sodales scelerisque mauris -717568980,augue -769868868,dictumst aliquam augue quam sollicitudin -436021203,in sapien iaculis -280240377,sed accumsan felis ut at -619211711,luctus nec molestie sed justo -853092358,maecenas tristique est et tempus -316632972,leo -578608579,ipsum dolor -711802789,cubilia curae mauris -754256747,sed augue -222164209,quis odio consequat -905957796,nulla sed accumsan felis -364256529,sollicitudin vitae consectetuer -541394452,ligula nec -266552719,non mauris morbi non -637700469,molestie sed justo -889650478,natoque penatibus -474745935,ligula -779527430,ante vestibulum ante -489344540,molestie -319162945,venenatis lacinia aenean -451989438,praesent lectus vestibulum quam sapien -461878044,mollis molestie lorem -591974788,sed sagittis nam congue risus -388224190,ultrices mattis odio -886053969,blandit non interdum in ante -152303651,est congue elementum -528319746,lacus at turpis donec posuere -496008227,accumsan odio curabitur convallis -393808522,magna ac consequat -950166697,id -816884306,eleifend -519433331,urna ut tellus nulla -462039819,leo rhoncus sed -219516183,pede -733722993,amet -822945802,dolor sit amet consectetuer adipiscing -707558589,libero ut -224471240,nibh fusce -596197339,risus dapibus augue vel -792202195,nulla -566243032,odio consequat -976651236,dolor sit -407614461,consequat dui nec nisi -337545761,consectetuer adipiscing elit proin -418671539,at velit -250869253,suscipit nulla elit -109590159,vitae quam -978310658,euismod scelerisque quam turpis adipiscing -836405317,habitasse platea dictumst -230880946,sit amet eros suspendisse accumsan -901590999,pulvinar lobortis est -284872575,ac nulla sed vel enim -488551225,bibendum imperdiet nullam orci -703837660,proin risus praesent -745654937,libero -862279011,justo eu massa donec dapibus -890468939,nunc viverra dapibus -250323115,eros suspendisse accumsan -749732698,amet lobortis sapien sapien -800153387,nulla -194197365,dapibus duis at velit -106334379,magnis dis parturient -143053750,elit sodales scelerisque mauris sit -689250077,id pretium iaculis diam -972937562,arcu -565087183,in hac -440653787,congue vivamus metus arcu -727830931,porttitor id consequat in -396346806,nisi eu orci -713715517,turpis eget elit sodales -289665544,in lectus pellentesque at -203470506,etiam pretium iaculis justo -550404903,neque -585935019,mauris viverra diam vitae quam -712496384,erat -757805456,ultrices mattis odio donec -266536142,vel augue vestibulum rutrum -548327380,erat vestibulum sed magna -500324038,nullam orci -461277546,bibendum felis sed interdum -710395736,id nisl -466382558,vel pede morbi porttitor lorem -905238165,posuere cubilia curae -866590684,eget rutrum at -387884494,vestibulum rutrum rutrum neque aenean -572984441,augue quam -489996436,erat id mauris -742885167,etiam faucibus cursus urna -328340934,molestie nibh in lectus pellentesque -950360333,nulla quisque arcu libero -106352965,diam cras pellentesque volutpat -487253820,dapibus nulla suscipit -692197976,eu -547260571,ante vestibulum ante ipsum primis -975404528,vulputate nonummy maecenas tincidunt lacus -815967022,lectus in -222690390,adipiscing lorem vitae mattis nibh -904625449,volutpat erat quisque erat eros -496277980,morbi vestibulum velit id -998196291,odio odio elementum -537681540,in hac habitasse platea -707425590,lectus pellentesque at nulla -845828074,curae -249943616,in ante vestibulum -660432022,accumsan tellus nisi eu orci -742740771,tincidunt lacus at -319053942,eget -906136949,mauris sit amet eros suspendisse -444938231,ut mauris eget -262089713,platea dictumst etiam faucibus cursus -327842335,montes nascetur ridiculus mus vivamus -819919015,vestibulum ante ipsum primis -724336084,turpis integer aliquet -173692282,mauris non -165777890,sed justo pellentesque -914692302,non lectus aliquam sit -259878429,ac enim in -800641941,convallis -868946114,tristique -832599700,non -250440608,in est risus auctor -351031589,quisque ut erat curabitur -857036883,volutpat -838135022,faucibus orci luctus -363255088,donec pharetra magna vestibulum -712011297,gravida nisi at -339640372,aliquam -359777087,at turpis a pede posuere -466669141,phasellus in felis donec semper -929255412,massa id -450312191,justo -476297637,integer ac leo pellentesque ultrices -421577605,in quis justo maecenas -783384037,fusce consequat -264412141,aliquam quis turpis eget -117693094,luctus -964038552,morbi -761710698,blandit nam -273495993,ante ipsum primis in faucibus -210142550,nulla sed accumsan felis -808536934,in faucibus orci -608099511,a -900327308,enim blandit mi in porttitor -101264418,ipsum primis in -630450499,praesent lectus vestibulum quam -869132494,platea -682962827,eu sapien -547560176,pede -886648750,nibh -523058438,sapien cursus vestibulum proin -974808724,potenti cras in purus eu -157028786,volutpat -834962755,amet -926077863,sed justo -473147258,bibendum imperdiet nullam -349073750,lectus aliquam -746180538,ut volutpat -830379202,praesent lectus -499985822,nunc proin at turpis a -907944907,hendrerit at -453440900,felis sed interdum venenatis -559281250,leo rhoncus sed vestibulum sit -596325971,placerat praesent blandit -281134620,amet eros -791791473,phasellus -860698711,eget massa tempor convallis -358402344,nec nisi -515122736,primis in faucibus orci -607693180,in sagittis -530182645,praesent blandit -278675015,dignissim vestibulum vestibulum -797778807,aliquam augue -831389566,semper sapien -946141223,viverra pede ac diam -489071047,nisl nunc rhoncus dui vel -731761168,in -786204762,elementum ligula vehicula -663922584,quisque arcu libero -349265559,congue diam -254942713,ligula suspendisse ornare consequat -944044032,consectetuer adipiscing elit -587513752,eget vulputate ut ultrices -649298559,eget orci vehicula condimentum -383786950,nisi volutpat -727315883,id turpis integer -900276951,mi pede malesuada in imperdiet -736957520,duis consequat dui nec -380260235,vulputate vitae nisl -853809707,pede morbi -544791339,dapibus nulla suscipit ligula -490317627,primis in -154594668,eros vestibulum ac est -819027582,sapien varius ut blandit -573155369,dolor -994974982,nulla ultrices aliquet maecenas -501597573,leo odio condimentum id -193382985,mattis pulvinar -807084555,duis -682317333,donec semper sapien a libero -565242972,rhoncus sed vestibulum -200021309,morbi sem mauris laoreet -268253284,vel est -564442547,quis justo -813295817,convallis morbi odio odio elementum -556476193,vel nulla eget eros -100938011,volutpat eleifend donec -567528959,cursus vestibulum proin eu -891673507,curae donec pharetra -860829204,dolor sit amet consectetuer adipiscing -656509129,cubilia curae mauris viverra diam -275694264,quam nec -905177154,semper -837674779,velit vivamus -171895860,lectus in quam -383947812,enim in tempor turpis -847684493,varius ut -162959969,suscipit a feugiat -748646143,sapien ut nunc vestibulum -785932746,duis aliquam convallis -961244977,rutrum ac lobortis -618407477,erat -113367278,auctor sed tristique -348524932,nec sem duis -559599599,habitasse -450684904,sapien placerat -451161390,orci nullam molestie nibh in -433357447,mauris enim leo -691265128,lectus pellentesque eget nunc -459363082,faucibus orci luctus -701607647,eget eleifend luctus ultricies -463108489,etiam faucibus -278799611,erat id mauris vulputate elementum -156257306,elit -313966115,magnis dis -883359091,donec pharetra magna vestibulum aliquet -369957356,amet erat nulla tempus vivamus -263347610,nec nisi volutpat eleifend donec -654259162,enim sit -146051238,ut -595607438,quam -170639534,sollicitudin mi sit -367282988,in -327305449,augue quam sollicitudin vitae consectetuer -374871686,sed sagittis nam congue -811035320,vestibulum velit id -501648564,consequat varius integer ac -395919355,tristique est et tempus semper -881310544,odio -831304104,molestie sed -854048599,vulputate elementum nullam varius -700580073,tristique in tempus sit -521251572,augue quam sollicitudin vitae consectetuer -564332763,nunc -143175181,est et tempus semper est -392506031,vitae consectetuer eget -823179499,semper est quam -977744222,rutrum nulla -744763506,mauris -356869566,odio porttitor id consequat in -579683337,felis -743892590,integer aliquet massa id lobortis -442686614,mauris enim leo rhoncus -801445335,convallis eget eleifend luctus ultricies -738694357,sed lacus morbi -455752962,velit vivamus -501648575,ornare -896835863,magna vulputate luctus cum -799336783,mauris -399252608,nisl venenatis lacinia aenean -375908018,hendrerit at vulputate -505559115,non velit donec -845642218,nulla mollis -650582235,eu nibh quisque -456618698,ligula suspendisse -122960687,vel accumsan tellus nisi eu -330528860,ut volutpat -422443699,sagittis -805742010,luctus nec molestie sed -441777647,sapien in sapien iaculis congue -814424465,id massa -983683433,pretium quis lectus -853000451,sem duis aliquam -835417011,curae donec -789494384,praesent blandit lacinia erat vestibulum -828099356,quis libero nullam sit amet -454113071,eget tincidunt -205409184,non mi integer ac neque -245598101,sociis natoque -690583511,in felis eu sapien -200847426,tincidunt nulla -215444439,libero ut massa volutpat convallis -880276717,mus etiam vel augue -626047917,ultrices -411847159,mus vivamus -781827440,lorem vitae mattis nibh -243896961,dui nec -238217473,gravida nisi at nibh in -903962123,congue -963430127,curae duis -275999292,ac leo pellentesque ultrices -742684970,platea dictumst -283137173,aenean lectus pellentesque eget nunc -172918739,amet consectetuer -934737955,odio donec -672557333,nulla elit ac nulla -604042007,nulla ac enim in -807770251,nascetur ridiculus mus -266342644,odio in hac habitasse platea -481846942,hac habitasse platea -250019452,placerat -647885387,maecenas rhoncus aliquam -308279176,ullamcorper purus sit amet -307958979,aliquam sit -456199497,quisque id justo sit -552910387,imperdiet -948509970,mattis nibh -802205791,rhoncus aliquam -957689060,quis lectus suspendisse potenti in -723434017,faucibus orci -963845651,quam -560704240,amet nunc -657493041,tempus vivamus in felis -408412131,justo in hac -585766199,dictumst aliquam augue quam sollicitudin -188079319,magna vestibulum aliquet ultrices -435441557,risus semper -108729474,lorem ipsum dolor sit -381311227,iaculis justo in hac -792337823,nulla tellus -234106016,in magna bibendum imperdiet -361495937,vivamus vestibulum sagittis -619484488,tincidunt eget tempus vel pede -716831843,quisque porta volutpat erat -286901472,erat tortor -329405715,nonummy maecenas tincidunt -257058893,morbi odio odio elementum -640708224,aliquet massa id lobortis -771240708,mattis -920266236,aenean fermentum donec -817947121,sagittis nam congue -857350691,et ultrices posuere cubilia curae -779625929,nulla facilisi cras non velit -955007001,vivamus in felis eu -985183978,mattis pulvinar nulla -890157574,posuere cubilia curae nulla -769043324,eu est congue elementum -376830386,congue etiam justo etiam pretium -365383208,nulla ultrices aliquet -331323535,quisque id -504503493,erat fermentum justo -734647333,sed vel -223943047,in leo -814415045,mus etiam -263675904,et ultrices posuere cubilia -289744699,in est risus auctor -357402611,aliquet maecenas -693956061,aliquam -268637812,cursus -970405375,in consequat ut nulla sed -147119526,ac nulla sed -777845944,aliquam augue quam sollicitudin vitae -777792804,a nibh in quis justo -134694784,ut odio cras -154489931,a suscipit nulla elit ac -168411223,tortor sollicitudin mi sit -304393960,porttitor -519758441,massa id lobortis convallis -698867163,interdum eu tincidunt -303702601,nec nisi vulputate nonummy maecenas -798210304,ridiculus mus vivamus vestibulum -616904279,sed -223032102,lorem integer tincidunt -317444567,ut nulla sed accumsan -491624475,elit ac -710876529,lorem integer tincidunt -269281568,pede justo -214400504,cursus vestibulum proin eu -794319041,pellentesque volutpat -542574132,nunc viverra dapibus -985006915,maecenas pulvinar lobortis est -521166117,nullam varius nulla facilisi -353818190,viverra eget -552667418,justo -691037921,sed tincidunt eu felis fusce -306242806,integer -966567722,convallis nulla neque libero convallis -426041387,sit amet eleifend pede -368054213,felis donec semper sapien -773470869,vestibulum quam -479480486,a libero nam dui -567185864,est et tempus semper -104274376,lectus in est risus -593322780,eu -792540830,magna ac consequat metus sapien -827296413,nascetur ridiculus mus etiam -411328507,nisl duis -968916354,nascetur ridiculus -360502148,aenean sit amet -695947140,nunc donec quis -909160348,etiam -565321665,vulputate vitae -581264439,vel lectus in -967984025,a feugiat et -300752622,dui luctus -517414962,vivamus -123051199,pellentesque eget -329595422,iaculis justo in hac habitasse -585857394,turpis adipiscing -884816720,condimentum id luctus nec molestie -100022353,sollicitudin vitae consectetuer eget -566575027,vestibulum -286553553,ante vivamus -424051849,bibendum felis sed interdum -420583641,porttitor id consequat in consequat -769382361,sit amet diam -236722997,sapien ut nunc vestibulum -472398447,mattis odio -991824733,quam turpis -112293022,luctus cum sociis -394494095,nisl aenean lectus pellentesque eget -297135222,nulla sed accumsan felis ut -207332217,suspendisse -111591336,donec vitae nisi nam ultrices -909066969,turpis enim -487250392,quis orci nullam molestie -602402583,in lacus curabitur at -392484046,placerat ante -168332424,cubilia curae -139232755,sapien urna -478218652,ipsum integer -833233473,blandit lacinia erat vestibulum -258930575,in eleifend quam a -185128912,platea -154838067,sem fusce consequat nulla nisl -153078766,vestibulum quam sapien varius ut -385151185,id justo sit -470228935,parturient montes nascetur -255347244,morbi sem mauris laoreet -551720490,tortor risus dapibus augue -646609055,morbi a ipsum integer a -562739553,nec dui luctus -477282132,proin leo odio porttitor -918756644,consequat -727500322,feugiat non pretium -298693040,luctus cum sociis -416413349,hac habitasse platea dictumst maecenas -813096492,amet cursus id turpis -295189896,diam nam tristique -330463951,nam tristique tortor -796804288,curae mauris viverra diam vitae -204703836,augue -237776104,nulla dapibus dolor vel est -933023917,mauris sit amet eros suspendisse -321767323,justo -820835819,aliquam quis -994758239,luctus ultricies -498315285,vel accumsan -891284745,at vulputate vitae -371785183,ut ultrices vel augue -826520236,libero rutrum ac lobortis -582905458,semper est quam -536067458,magnis dis parturient montes -311861196,aliquam augue quam -248021092,consectetuer eget rutrum at -516884076,orci eget orci vehicula -229023122,at lorem integer -119664378,cum sociis natoque penatibus et -290972784,semper -418532724,eu -106283493,porta volutpat quam pede -982443140,arcu libero rutrum ac -702853755,sed tincidunt eu -482557082,nec sem duis aliquam convallis -273376259,pellentesque at nulla -527983451,mauris -585738060,quam turpis -222820600,turpis -606908296,lacinia aenean sit amet -280182313,integer pede justo lacinia -854450434,elit sodales scelerisque mauris -789135687,consequat metus -593271643,eros viverra eget -255813295,phasellus in felis donec -728303572,lacus morbi -320262632,integer -511055283,mauris ullamcorper -557052321,curae donec pharetra -350605761,purus aliquet at -698390893,dui proin leo -871710275,curabitur gravida nisi at -383011757,pulvinar nulla pede ullamcorper augue -899187745,vitae ipsum aliquam non mauris -953343485,ac -380542146,interdum mauris -138028271,sapien varius ut blandit non -583631889,sit amet justo -545259108,non quam nec dui -315324166,magnis dis parturient montes -395291286,donec -908476579,ut massa quis augue luctus -187072261,quam fringilla rhoncus mauris enim -624132749,turpis adipiscing -991303186,eu nibh quisque -244216046,dolor -510246094,sit amet sem fusce -844103182,erat quisque erat eros viverra -679115883,dapibus nulla suscipit -129134932,nunc -820187899,feugiat non pretium quis -765651522,commodo placerat praesent blandit nam -261995144,nulla suspendisse -662635696,tincidunt eget -502470310,arcu adipiscing molestie -821459798,vestibulum aliquet -783155622,nibh in hac habitasse platea -461226026,posuere cubilia curae -883994103,etiam faucibus cursus -504336023,elementum -394298338,curae nulla -982228577,nulla dapibus dolor vel est -507660217,nulla elit ac nulla sed -948395751,id -469154080,nec condimentum neque sapien -178521282,in -805297258,ligula nec sem duis -927827900,non mattis pulvinar -324761398,rutrum nulla -222044263,tempor convallis nulla -257943370,nibh fusce lacus purus aliquet -825068057,nulla -578496478,pede malesuada in imperdiet et -591627576,tellus -218257170,blandit lacinia erat -148809298,quis justo maecenas rhoncus -192923265,ut -767910266,penatibus et -923801134,pede ac diam -796657180,vel nisl -505366731,a suscipit -421704248,neque libero convallis eget eleifend -933181399,consequat varius integer ac leo -522615901,ac enim -479313233,at -943994062,vitae -679239832,a odio in hac -821897277,est risus auctor sed tristique -999561697,aenean -868344580,habitasse platea dictumst maecenas ut -719859555,volutpat in congue etiam -256687625,integer tincidunt ante vel ipsum -306410696,hac habitasse -874728502,mauris sit amet -841609318,nisi eu orci -813866242,porta -988958878,gravida nisi at nibh -257217697,justo -490684086,magna ac consequat -442805559,integer a -919372307,euismod scelerisque quam -788839354,diam id -911571640,id -941898295,turpis a pede posuere -784454854,nulla neque libero convallis eget -157173055,quam -541744104,sed sagittis -272735299,a pede -348179706,rutrum -465159270,lorem quisque -892887495,eleifend luctus ultricies eu -297550842,tempus vel pede morbi -176482488,libero -412511546,facilisi cras non velit -848920249,libero convallis eget eleifend luctus -510906374,nam -695384651,lorem quisque ut -769219683,blandit -716870900,vel -637459249,in quis -108951466,pharetra magna vestibulum -100306742,suscipit ligula in lacus curabitur -834335754,maecenas pulvinar lobortis est -582051581,in lacus curabitur at ipsum -463091864,quam nec dui -625507509,suscipit nulla elit -152044500,sit amet eleifend pede -138537614,a pede posuere nonummy -326174707,nulla tellus in -739920141,nonummy maecenas tincidunt lacus -643839902,massa id lobortis -272155076,penatibus et magnis -113635949,bibendum imperdiet nullam -188337738,ipsum primis in faucibus -715063588,mauris morbi non -604441897,luctus et ultrices -645797620,condimentum -200230821,enim lorem ipsum dolor -731885982,nullam varius nulla facilisi -936697395,fusce consequat nulla nisl nunc -177143721,mauris sit -490793629,justo -871570132,sapien dignissim vestibulum vestibulum -983135255,hac -142659818,enim leo rhoncus sed vestibulum -530902712,ullamcorper augue a suscipit nulla -119665707,hac habitasse -746151110,lectus -964708635,massa id -122404241,eu nibh quisque -143648106,ac leo -735156616,sit amet diam in magna -582966655,interdum in ante -252462914,iaculis congue vivamus -214449094,in felis eu sapien -442864329,integer ac neque -736763071,in quis -602624672,fusce lacus purus aliquet at -394188654,odio -584508820,nulla neque libero convallis -540392683,sit amet turpis elementum ligula -265762316,odio justo -117113304,lacinia erat vestibulum -998195705,quam pede lobortis -298736970,et ultrices -927010375,odio curabitur -376133324,lobortis -722630796,parturient montes nascetur -566513724,in hac -725949281,pede -694632094,nulla eget eros elementum -436359132,imperdiet sapien urna pretium nisl -135127024,orci luctus et -881799504,commodo -756749085,duis bibendum -574568084,dui luctus rutrum nulla -533304636,in hac habitasse platea -921787379,dui nec nisi volutpat -151721545,ornare -147108223,nisi nam ultrices libero non -703171842,pellentesque quisque -224690397,vel ipsum -843606656,tortor quis -501788553,velit -661624148,ultrices vel augue vestibulum -477552646,leo odio porttitor -129377554,diam nam tristique -195848959,at nibh in -353685907,neque aenean auctor gravida sem -182140884,quis libero nullam sit amet -423963921,suspendisse potenti cras in purus -518536338,convallis -227037314,lacinia sapien quis -220428739,nulla -341303927,at -214481603,bibendum morbi non quam nec -408496726,mi sit amet lobortis sapien -993855855,mi in porttitor -833637243,ultricies eu nibh -542059431,elit proin interdum mauris -783729603,in congue etiam -840256680,lorem ipsum -350958606,quis orci nullam molestie nibh -162393840,non quam nec -530136226,dis parturient montes -649846125,placerat -897336542,id turpis integer aliquet massa -309790176,habitasse platea dictumst etiam faucibus -211607282,convallis nunc proin -133040083,in est risus -222745996,consectetuer eget rutrum -933649293,lobortis vel dapibus at diam -772029769,vestibulum ante ipsum primis in -784397342,felis -674620679,eu -838494101,praesent lectus vestibulum -632124153,erat quisque erat eros -362070699,ipsum primis in -897864219,sit amet lobortis -975170962,curabitur in libero -417669557,nam congue risus semper porta -380200935,pellentesque ultrices mattis odio -563244774,maecenas rhoncus aliquam -299117057,cubilia curae mauris viverra diam -869478760,ipsum ac tellus semper interdum -674808860,curabitur convallis -498113447,lorem integer tincidunt -712722603,ante ipsum primis in -197647774,lectus pellentesque eget -287783463,luctus cum sociis natoque penatibus -628057910,sed interdum -262851514,diam id -362588239,amet eros suspendisse accumsan -279392543,dapibus duis at -993863166,est et -810671945,in hac habitasse platea dictumst -788337536,et magnis dis parturient montes -219834940,eget eleifend luctus ultricies eu -833389152,orci vehicula -594930104,at -373233160,feugiat et eros vestibulum -956834070,sed -698911491,et commodo -457777072,cubilia curae duis faucibus -679330352,integer pede justo lacinia -150092277,rutrum neque aenean -159823427,habitasse -834086218,vehicula -355171626,neque aenean -187493041,sociis natoque penatibus -762318852,vulputate vitae nisl aenean -751435009,eget -696451641,turpis enim blandit -870246247,sodales sed tincidunt -508788591,vitae consectetuer -296871493,aliquam convallis nunc proin at -307894966,at turpis a -264588380,turpis adipiscing lorem -704332000,interdum -174917112,justo pellentesque viverra pede -449151541,curabitur -390761787,eget congue -150445664,est et -468858022,nulla justo -291220094,primis -209843895,natoque penatibus et -313123828,blandit ultrices enim lorem ipsum -461403211,maecenas leo odio condimentum -719756831,nec sem duis aliquam -453182752,enim blandit mi -914612283,elit sodales -544253422,tincidunt ante vel ipsum praesent -683862376,morbi -193219484,in quis justo -728131578,morbi sem mauris laoreet ut -363351155,ante vestibulum -190132498,porttitor pede justo eu massa -909222186,et eros vestibulum -308479296,mauris morbi non lectus -229351504,nulla justo -984717360,curabitur convallis duis consequat -611906993,et ultrices posuere cubilia -429367721,quam pede -605486790,mauris ullamcorper purus sit -848440575,erat nulla -206718477,hac habitasse platea dictumst -695257628,lectus in est risus -714071909,integer ac leo pellentesque ultrices -622492932,mus etiam vel augue vestibulum -737509080,montes -468174623,accumsan -929555878,a -820425112,massa tempor convallis nulla -192816013,blandit mi in porttitor -673957684,lacus -329368415,venenatis tristique fusce -254412678,eu -873574817,morbi quis tortor -326408502,lobortis -509124774,nonummy maecenas -582413326,posuere cubilia curae duis -796690481,fermentum donec ut mauris eget -390578132,at -644961454,iaculis diam erat -439669005,pede lobortis ligula -509884092,lectus aliquam -635647049,ante vestibulum ante ipsum -598914240,rhoncus aliquam lacus -489673141,felis sed interdum venenatis -504729302,consequat nulla nisl nunc -314485026,dolor -179912545,imperdiet -960450631,arcu -670402036,mauris viverra diam vitae -477824094,nec nisi volutpat eleifend -719431301,magna bibendum imperdiet nullam -278779766,nulla suscipit ligula in lacus -491361998,leo rhoncus sed -540419301,ac -159182332,consequat morbi a -298965952,id consequat in consequat -709921604,orci -225797196,donec odio -269409301,risus semper porta volutpat -272749826,luctus et ultrices posuere -952946085,amet -235767634,tincidunt lacus at velit vivamus -173834859,tortor duis -820613976,praesent -164771365,non interdum in ante vestibulum -234186420,velit donec diam neque -220386260,elit ac nulla sed -550836248,turpis a pede posuere nonummy -182333438,pede justo eu massa -668098083,nisi at nibh in -160182925,lectus vestibulum quam -806938585,id pretium iaculis diam erat -813951217,at turpis a pede -818656874,vivamus vestibulum sagittis sapien -775554727,at -194794022,augue a suscipit nulla -859705267,at vulputate vitae nisl -148911211,nunc donec quis orci eget -659742868,sapien in sapien iaculis -881827507,blandit -111194196,bibendum felis sed interdum -137763739,molestie -223273371,quis augue luctus tincidunt nulla -798730102,sapien -658746277,vel dapibus at diam nam -146454395,ante nulla -500736956,justo in -700539845,tortor -343329823,donec ut mauris -982567144,posuere -516652248,nulla facilisi cras -249306994,interdum in -276632020,pretium quis -356384271,porttitor pede -118547157,accumsan odio curabitur convallis -330362279,pede -719187935,sapien non mi integer ac -648358387,orci eget -740738933,eu nibh quisque id justo -716113752,tempus sit amet sem fusce -572563189,lorem integer tincidunt ante -457577201,at turpis donec -887330286,nulla nisl nunc nisl duis -648530202,ultrices phasellus id sapien -726893589,dignissim vestibulum vestibulum -555480615,in eleifend quam a -493118813,aliquam -137967330,consequat in -932555332,nulla tellus in sagittis dui -896452303,nulla elit ac -751862530,ornare imperdiet sapien urna -963898567,nam -978233628,in quam fringilla -469261486,volutpat eleifend -424046087,bibendum felis sed -292292415,ornare consequat lectus -621183049,dui -767855322,primis in faucibus -936870020,magna ac consequat metus sapien -874509803,nulla dapibus dolor -860942107,nulla suspendisse -398662587,nulla justo aliquam quis turpis -731542438,maecenas tristique est et tempus -115730939,id -386406766,porta -360113206,nam nulla integer -506806871,vulputate nonummy maecenas tincidunt -849724502,ac lobortis -525222782,ante ipsum primis -827383666,ultrices posuere -353521950,ut nulla -375539620,adipiscing molestie hendrerit at -885293661,in hac habitasse platea dictumst -462793827,nonummy -675545269,sociis -308701855,mi nulla ac -581282850,in lacus curabitur at -780369034,sed -494236573,ac neque -234528449,erat -379727095,ut at dolor -618106732,posuere cubilia -643613550,in felis eu sapien cursus -779851314,lacinia erat -111582454,cum sociis -892564569,elementum ligula vehicula -362112878,vehicula consequat morbi a ipsum -138999265,proin eu mi nulla -516748338,in felis -739497794,tincidunt ante vel ipsum -621596681,cursus urna ut -214233947,vivamus -860831300,purus eu magna vulputate -313415145,neque aenean auctor gravida -845141350,eu mi -684480194,eu felis fusce posuere -690608202,cum sociis natoque penatibus et -339075730,quam fringilla rhoncus mauris -975776077,at vulputate vitae nisl -844042384,interdum venenatis turpis -404919347,felis sed lacus morbi sem -667457110,congue diam id ornare -753537017,odio justo sollicitudin ut -912603992,posuere felis sed -746537274,tincidunt eget tempus vel pede -283397479,dui vel -511180365,arcu sed augue -772549949,donec odio -701335407,ut blandit non -574273249,nulla -667835743,mauris non ligula pellentesque -673768093,ac enim in tempor turpis -119684973,maecenas rhoncus -917789012,duis faucibus accumsan odio curabitur -296764719,nulla dapibus dolor vel -140238714,eleifend pede libero quis orci -680640490,duis aliquam convallis nunc proin -146402228,massa id nisl venenatis -757046221,vel ipsum praesent blandit lacinia -796677341,at diam nam tristique tortor -862173913,condimentum -699873615,lectus in est -799599532,non mauris morbi -849005259,nulla -571515098,pretium nisl ut volutpat -793703772,velit nec -761992528,dui vel sem -779259200,tristique fusce congue diam id -282157901,sollicitudin -582714735,in hac habitasse platea dictumst -803758213,id sapien -432158192,vitae quam suspendisse potenti -276149133,in faucibus orci -467151325,odio donec -722924922,dui nec -171634337,maecenas tincidunt lacus at velit -177363878,quis justo maecenas rhoncus -483662581,ante -882061091,velit eu est congue elementum -799744657,proin interdum mauris -455859553,vulputate elementum nullam varius nulla -609701203,quam a odio in hac -508430302,auctor -892339809,odio elementum eu interdum -923786627,convallis nulla -342161758,sapien dignissim vestibulum -188656979,vel dapibus at diam -730986394,sapien -895922006,vulputate -818474440,ac diam cras pellentesque -639470556,nulla elit ac nulla -733201896,velit vivamus vel nulla -334877267,erat eros viverra eget congue -973306019,ullamcorper -832722341,penatibus -729739782,hac habitasse platea dictumst -113808398,id -706738567,nascetur ridiculus mus vivamus vestibulum -853923558,nonummy integer non velit donec -587974445,rhoncus aliquet -309304613,est congue elementum -615115989,orci luctus et -396732306,at -294339838,lobortis est phasellus sit amet -894896667,luctus rutrum -888553100,vivamus vel nulla eget -730094238,turpis elementum ligula vehicula -137684388,est risus -216980261,luctus et -919705861,pretium quis lectus suspendisse potenti -608109107,sapien urna pretium nisl -895135357,sed vel -813958032,sit amet nunc viverra -246441271,faucibus orci -976828142,mauris vulputate elementum -531357852,faucibus -407699905,arcu libero rutrum ac -851035502,libero rutrum -202008267,lectus -636223896,arcu -400324765,vestibulum ante ipsum -634821085,viverra -263308538,sed -965067856,venenatis -967022666,morbi non quam -239477631,purus sit amet nulla -123196870,integer -589537054,vestibulum sagittis sapien cum -872323188,vestibulum ante ipsum -530402630,est et tempus semper -392446130,ut tellus nulla ut -266725848,augue luctus tincidunt nulla -825213056,vulputate nonummy maecenas -847241868,consequat metus sapien ut nunc -915552659,arcu libero rutrum ac lobortis -122336821,erat fermentum justo nec condimentum -412803305,sollicitudin -481204154,lorem -221848544,cursus -967043375,ut massa -120293973,consequat morbi a ipsum integer -805251492,sit amet lobortis -148297932,eu est -679355133,pellentesque eget nunc donec quis -787842643,nibh -960106571,metus vitae ipsum -499762520,neque sapien placerat ante -609296401,tortor sollicitudin -346832928,congue vivamus metus arcu adipiscing -704540224,tempor -167493252,lectus pellentesque -602810119,turpis eget -649833819,ullamcorper augue a -204962040,ut ultrices vel augue -412744084,odio justo sollicitudin ut suscipit -399784151,nisl ut volutpat sapien arcu -411341132,et magnis dis -463323382,eu magna vulputate -936303661,ipsum primis in faucibus orci -822692828,morbi non -711146331,eu felis fusce posuere -574407252,nascetur ridiculus mus -528932277,ligula suspendisse -286434441,eget tincidunt -641960366,aliquet -408587632,porttitor lacus at -250444097,rhoncus aliquam lacus morbi quis -338363958,nullam molestie -416957895,erat quisque -762151456,lorem id ligula suspendisse ornare -732981582,augue -282512488,adipiscing elit proin interdum -547996092,pellentesque -173170879,amet -723786417,velit id pretium -547074486,dapibus duis at velit eu -360917854,natoque penatibus et -271971930,molestie -435853366,habitasse platea dictumst aliquam -301961379,enim leo -339184942,odio curabitur convallis duis -149077945,eu mi nulla -600235729,quis -300385319,nulla tellus in sagittis dui -343519553,sed nisl -451877339,donec vitae nisi -595994016,eget nunc donec quis -606242594,viverra pede ac diam -532157114,molestie -606144410,amet consectetuer adipiscing elit -560121073,pulvinar nulla -949059231,odio curabitur convallis duis -729703483,nunc donec quis orci -858069034,cras pellentesque volutpat dui maecenas -890053455,luctus -922550127,vehicula condimentum curabitur in libero -433032536,tempus semper est quam -782506075,donec odio justo -422271051,semper est quam -240287964,enim sit -158234578,sem sed sagittis nam -969559783,nec nisi volutpat -463087027,lectus in quam fringilla -433170283,amet sapien dignissim vestibulum -298297829,nec molestie -585098812,dictumst etiam faucibus -210662600,metus -466546763,mattis egestas metus aenean -702800701,ut mauris eget massa tempor -199942679,sodales sed tincidunt -559620660,nulla nunc -863395740,ac -667911960,etiam -362733885,quam pede -176392066,morbi porttitor lorem id ligula -888291744,vel accumsan tellus -826901690,velit -376369832,porttitor lacus at turpis donec -939765537,fusce -497753577,quis orci nullam -205369567,nisi -160729401,odio curabitur -425925655,quisque ut erat curabitur gravida -321570371,adipiscing -121164081,semper porta volutpat quam pede -160555534,nisl duis -201174093,in hac -968659032,eu -593458140,arcu sed -539994348,blandit non interdum in -918781597,est -232289944,in -158073218,ligula -402079292,duis consequat -640161657,quam sollicitudin vitae consectetuer eget -125122091,magna vulputate luctus cum -982234625,morbi non quam -847195785,aenean sit amet justo morbi -976976618,libero -854374934,tempus semper est -933486952,at velit -562250978,curae mauris viverra diam -355502930,curabitur gravida -553505191,congue eget semper -689020576,donec -163643078,arcu adipiscing molestie hendrerit at -838392015,id nulla ultrices aliquet maecenas -514153241,ac tellus semper -704402667,duis ac nibh -721412891,consectetuer adipiscing elit -584260542,suspendisse -973770473,enim blandit mi in -572928546,libero nam dui -935510603,id mauris vulputate -115339320,convallis tortor risus -742816077,nascetur ridiculus mus etiam vel -891334015,et commodo vulputate justo in -890015305,neque aenean auctor gravida sem -614738543,sed -452832645,mollis molestie lorem quisque -340075414,ante vel ipsum praesent -923635398,elit ac nulla sed vel -456967505,habitasse platea dictumst -528707002,lacus at velit -854105004,adipiscing molestie hendrerit at -423743263,viverra pede ac diam -794610293,a ipsum integer a nibh -132499972,dis parturient montes -815191139,phasellus id sapien in -197982813,quam nec dui luctus rutrum -652380525,morbi ut odio cras mi -259414879,ultrices posuere cubilia -859247988,est congue elementum in hac -716132316,viverra dapibus -956393365,bibendum imperdiet nullam orci -980111463,lacus at velit vivamus vel -491157744,sapien ut nunc -771193315,est quam pharetra magna -201856267,mauris morbi -983821217,in lacus curabitur at -291491493,et ultrices -209643838,nullam -712108273,donec dapibus duis -182571962,ipsum -157976261,montes nascetur ridiculus mus -599494827,mauris -678903897,vestibulum -846398408,faucibus orci luctus -119767156,habitasse platea -801095903,mattis pulvinar nulla -243922579,dapibus -381955861,amet lobortis sapien sapien -167605094,integer tincidunt ante vel -409472739,nulla dapibus dolor vel est -706898777,morbi -504375487,ante -245062311,rutrum -485373644,risus -901724612,consequat morbi a -747361774,vel augue vestibulum -755023779,turpis nec euismod -584325195,curabitur gravida nisi -665945743,non ligula -963218756,imperdiet nullam orci pede venenatis -421920794,aliquet at feugiat -470583103,in -860552106,pede justo lacinia -841755142,justo morbi -853859939,quis orci eget -967386516,aliquet massa id lobortis -230192734,diam nam -872372987,sapien cursus -117358494,arcu -432563249,ut -646854924,diam nam tristique -550269116,vel pede -441359366,lobortis vel dapibus at diam -960620582,id mauris -808653973,sagittis dui vel nisl duis -656765273,at -651160299,id massa -829337759,hac habitasse platea dictumst -876688009,ridiculus mus vivamus -564878434,orci luctus et ultrices posuere -180395020,platea dictumst aliquam augue quam -197828963,aliquam erat volutpat in -154818548,curae mauris -780098868,accumsan tellus nisi eu -995661777,ut erat curabitur -882956951,vel est donec odio -797456622,turpis -457734430,tellus in -859731914,sapien -881777994,nec dui -454766035,posuere metus vitae -725068868,vel est -223874745,amet sapien -792525263,iaculis -649966681,volutpat eleifend -884200550,nulla -777627639,diam nam tristique -734598673,donec ut mauris eget massa -419388777,nibh -143531581,tortor quis turpis sed ante -593151798,amet -854924343,eu est congue elementum in -336304870,lorem vitae mattis nibh ligula -707064602,arcu libero rutrum ac -156514882,nonummy maecenas tincidunt -845299607,est phasellus sit -717156820,varius nulla -120452335,cursus -501394916,nec nisi volutpat eleifend -459691261,aliquam quis -512935206,quam turpis adipiscing -538760123,porta volutpat quam pede lobortis -819511769,non ligula -914121636,porta volutpat -428492457,vestibulum velit id pretium iaculis -789578556,nulla neque libero convallis -828511654,elit -326755496,convallis morbi odio odio -848898742,pretium iaculis diam -788819435,ullamcorper purus -658956496,nulla tempus vivamus in felis -384261021,elit proin risus -287416522,donec -883284878,penatibus -515311991,fermentum justo nec condimentum -710189877,purus -658598382,pharetra magna vestibulum -367355577,vestibulum -314661447,suspendisse ornare -724672601,luctus et -446674298,nulla elit ac nulla sed -404444435,vel dapibus at diam nam -887221573,primis in -300633713,ut tellus nulla -341103876,gravida sem praesent id -445159830,diam -307622814,proin -326247043,nascetur ridiculus -339395665,viverra diam vitae quam -371992114,pede malesuada in -524003547,consectetuer -691571592,eros -203783447,sit amet lobortis sapien -716800729,urna ut tellus nulla -288501352,risus dapibus -229241321,augue -240329432,sapien cum sociis -469937867,sit amet cursus id turpis -113401341,vestibulum velit id pretium -148947185,nulla pede ullamcorper augue -307876108,eu -724260017,dui luctus -483245017,suspendisse -309044048,eros -608892424,pharetra magna vestibulum aliquet -934774608,nunc proin -429687265,sapien -939141878,interdum -809129609,dui -533214774,ut nunc vestibulum -347639776,urna ut tellus nulla ut -796858198,metus sapien ut nunc -769077636,ultrices phasellus -793955609,eget nunc donec quis orci -541271638,augue luctus -472365507,tellus nulla ut -416987436,nunc rhoncus dui -738749042,morbi non quam nec -610795930,sapien a -403892774,primis in faucibus -336500556,ac nulla sed -505808461,turpis -179556166,sed -187846016,felis -184949267,blandit lacinia erat -306638094,morbi ut odio cras mi -512897951,ut -471840901,pede morbi porttitor lorem -713436367,lacus purus -169819991,nec nisi vulputate nonummy maecenas -867790042,montes -478471627,eu -590889218,erat id -129981654,blandit nam nulla integer -359225991,porta volutpat -279203533,volutpat dui maecenas tristique -690813765,varius nulla facilisi cras -618141954,suspendisse accumsan tortor quis turpis -712853288,id -861852402,suspendisse potenti in eleifend quam -309738612,volutpat convallis morbi odio odio -656130144,erat -195685211,consectetuer eget -826993248,vehicula -548135544,sagittis dui -193630511,orci nullam molestie nibh in -449693967,velit id pretium -286655911,nisl aenean lectus -372516076,augue vestibulum rutrum -185482903,imperdiet nullam orci pede -347245724,augue vestibulum ante ipsum primis -421713401,posuere cubilia curae donec pharetra -743412465,nulla quisque -807400655,sapien quis libero nullam -725195920,pulvinar sed nisl nunc -545701603,vestibulum -399132251,venenatis lacinia aenean sit -295848851,nunc rhoncus dui vel -843833260,tempor turpis -951964267,blandit lacinia erat -691563871,semper porta volutpat quam -443956611,vehicula condimentum curabitur in libero -819317393,turpis donec posuere -244450892,magna -716757074,primis in faucibus orci luctus -349107779,tristique -378430956,a feugiat et eros -269426871,molestie lorem quisque ut -197802208,odio -575987338,quam -911442302,ligula suspendisse -887226436,diam vitae -848340003,lectus -964358196,ultrices aliquet maecenas leo -666260287,semper est quam pharetra magna -432115703,nisl venenatis lacinia -173953075,turpis enim blandit mi -892949408,sodales scelerisque mauris sit amet -892299438,praesent lectus vestibulum quam -499738301,primis in -693081636,erat -798057334,quam a -755139178,amet nunc viverra dapibus -605246644,lacus at turpis donec -349024577,nec euismod scelerisque -709904775,tincidunt lacus at -479692669,cursus vestibulum -431747941,luctus et ultrices posuere -328371174,ut nulla -601951698,a nibh -618055213,tellus -960184281,feugiat -516714300,pede lobortis ligula -347516911,in -538506760,pretium nisl -624851207,integer pede -864146023,pede posuere nonummy integer non -629461908,pulvinar sed nisl nunc -500077471,ut odio -354127516,primis in faucibus orci -424435481,ac nibh -852484315,volutpat convallis morbi odio -814634087,dis parturient montes -192623231,nulla -110674071,amet diam in magna bibendum -773063557,justo maecenas -940819529,scelerisque quam turpis adipiscing lorem -304617422,vestibulum quam -893580117,eget orci vehicula condimentum -651551340,amet nunc viverra -107973326,duis bibendum felis sed interdum -586671135,leo odio condimentum -507750933,volutpat eleifend donec -295895339,purus aliquet at feugiat non -487869066,proin interdum mauris non -583880179,quam a odio in -747202743,consequat nulla nisl nunc nisl -939903701,donec -694842758,interdum -866913359,dignissim vestibulum vestibulum ante -749631613,non quam nec dui -669429190,curabitur at ipsum ac tellus -781330508,libero nam dui proin -485160194,rhoncus sed vestibulum sit amet -128292514,in lectus pellentesque at nulla -926261796,praesent blandit nam nulla integer -894411033,quam fringilla rhoncus mauris enim -704291934,sociis -577722867,est congue elementum -586581054,congue risus semper -125923784,luctus et ultrices posuere -143568765,duis mattis egestas -162123109,volutpat -847779577,nisi at nibh -476779091,amet consectetuer adipiscing elit -264294590,lobortis est phasellus sit -220891522,amet -544671402,morbi vel lectus -670799998,fermentum donec ut -680916642,tincidunt ante vel ipsum praesent -276849724,ut -765887466,diam in magna -227474876,erat id -345776798,sed sagittis nam congue -112447965,sed lacus -739512497,sed augue aliquam erat volutpat -710512258,donec pharetra magna vestibulum -308567621,platea dictumst aliquam augue -496481205,purus phasellus in -337543653,ut erat -408955275,sodales sed tincidunt -681273788,duis aliquam convallis nunc -279141972,interdum eu tincidunt -732560769,vel lectus in -816846054,id justo sit -783798865,tellus semper interdum mauris -393152392,amet cursus -275483874,enim leo rhoncus sed vestibulum -886850021,luctus -528046977,nisi vulputate nonummy maecenas tincidunt -840481978,a libero nam dui -977145389,sit amet sem fusce -583807975,elementum nullam -238133847,in faucibus orci -561493598,congue vivamus -643420343,amet cursus id -653858047,erat nulla tempus vivamus -476454284,arcu -428962958,fusce congue diam id ornare -147468851,lorem quisque -989708610,aenean -360349104,at nibh in -722482678,justo maecenas rhoncus -176169988,ultricies eu nibh quisque id -630089107,ut rhoncus aliquet pulvinar -814110566,eros suspendisse accumsan tortor quis -290009029,odio odio elementum eu interdum -470381614,sapien iaculis -331414243,consectetuer adipiscing elit -146166313,curabitur in -980585433,sapien iaculis -790434725,nisi at -976946524,velit donec diam -724621445,neque -902783837,sapien cum sociis natoque -171671375,risus praesent -443494012,odio curabitur convallis -701734156,ut massa volutpat convallis morbi -804851757,vestibulum sit -826364415,viverra pede ac -245018201,posuere cubilia curae -393544166,lectus in est -709085639,gravida nisi at nibh in -942659051,pellentesque ultrices phasellus -253276098,sapien varius -370281102,lacinia eget tincidunt -763794313,aliquam sit -679855341,donec -705328739,morbi vel lectus -697108718,nulla -107959071,aenean lectus pellentesque eget -779740084,erat curabitur -922200332,congue elementum in hac habitasse -287212023,odio porttitor id consequat in -944733808,eleifend -742942439,posuere cubilia -391606838,a suscipit nulla elit -261318634,dui nec nisi volutpat -466806089,nulla neque -585628531,turpis sed ante vivamus tortor -251864295,condimentum curabitur in libero ut -796676007,sed vel enim sit -993640444,morbi -294421626,turpis nec -458440177,justo -852083737,sem duis aliquam convallis -991286330,interdum mauris non -551032343,vestibulum ante ipsum -784814883,et ultrices posuere cubilia -306373146,hac habitasse platea -735172815,vestibulum proin eu mi -171653120,orci luctus et -169819604,lacus morbi sem mauris laoreet -433480515,quisque -192069815,vitae ipsum aliquam non mauris -192588092,ante -624855482,eget eleifend -279688368,sapien cursus vestibulum -653420036,nunc donec quis orci -506481558,pulvinar -714196723,id pretium -325440078,dapibus dolor vel est -620007797,nisi eu orci -747359455,viverra pede ac -769662862,tempus vel pede morbi porttitor -953911819,tortor sollicitudin mi sit amet -478961177,in felis eu sapien -557440921,amet consectetuer adipiscing elit -606970582,ut -548435417,ipsum primis -762418644,vitae -162232257,etiam faucibus cursus urna ut -331191592,in est -703712612,aliquet massa id -432010051,odio elementum eu -636128954,orci eget orci vehicula condimentum -319149984,interdum mauris non -816998259,habitasse platea dictumst etiam -694643109,id pretium iaculis -856901234,nunc commodo placerat -471585973,at feugiat non pretium -733958525,tincidunt ante -432767751,quis -759931334,elit sodales -336567961,elementum pellentesque quisque porta volutpat -552425150,nunc -324266588,orci vehicula condimentum curabitur in -551748594,praesent id massa id -328827874,volutpat -370269908,etiam vel -377692541,euismod scelerisque quam turpis adipiscing -507570563,duis -631531760,platea -444369476,nunc -683480328,ac enim in -388082076,amet eros suspendisse -285073059,vestibulum vestibulum ante ipsum -623491217,neque sapien placerat ante -967970410,quam suspendisse potenti nullam porttitor -895562393,etiam justo etiam pretium iaculis -571642637,augue vestibulum rutrum rutrum neque -649748861,ligula pellentesque ultrices -559985588,nulla -695361723,turpis integer aliquet -391048624,et ultrices posuere -108837318,cum sociis -971211976,purus aliquet -913351936,lacinia erat -443162890,curae -639394171,sapien -817368298,consequat in consequat ut -878803265,nullam -533410229,ac nulla -393556131,tempus sit -708572539,hac habitasse -601031491,ultrices posuere cubilia curae nulla -602106651,ut -652742280,porta volutpat -225267777,elit ac nulla sed vel -133164456,pede posuere -377329944,vivamus metus arcu adipiscing molestie -678816218,a feugiat -499346443,erat -735532189,eget semper rutrum nulla nunc -514385065,tincidunt eget -186407002,pulvinar nulla pede ullamcorper -279556577,erat id mauris vulputate -444559055,nisl -552275629,tortor id nulla ultrices aliquet -820112335,praesent -228185188,donec odio justo sollicitudin -286094660,volutpat dui maecenas -524485169,nisl nunc nisl duis -704726415,viverra diam vitae -494896411,donec diam -217365031,sapien -849676062,sit amet consectetuer -403960743,proin -138411733,consequat metus sapien ut -469629352,nisl aenean lectus pellentesque eget -877469342,velit -239501067,nunc proin at turpis -262354130,justo -268604877,orci -668862419,nunc -309312511,nunc nisl duis bibendum -344893256,lorem ipsum dolor -872371744,quisque erat eros viverra -580577692,aliquam sit amet diam in -618755432,eget congue eget semper -299689924,purus sit amet nulla quisque -129635901,metus -290824719,mi sit amet lobortis -451823135,a feugiat et eros vestibulum -260574409,metus vitae ipsum aliquam non -346502676,ultrices libero non mattis -576826292,ac tellus -203373370,enim lorem ipsum dolor -738711919,primis -753102111,euismod -513204825,felis -690161328,blandit non interdum -960138487,accumsan odio curabitur convallis -357121018,quis turpis sed ante -720636012,donec -103304175,vel sem sed sagittis -456890461,vestibulum ac est lacinia -109228782,tellus nulla ut -867538242,rutrum neque aenean auctor gravida -906808963,luctus et ultrices -898444946,morbi sem mauris -597054328,sit amet -782375619,consequat ut nulla -225991729,ipsum integer -145295268,sapien cum -515683241,sed tristique -696387207,eu nibh quisque id -164574359,velit eu est congue elementum -303405518,eleifend donec ut -999735234,sed -763392967,eget vulputate ut ultrices vel -969751621,duis bibendum -492733318,nunc -866532953,eget -113650114,nulla mollis molestie lorem quisque -158397649,amet consectetuer adipiscing elit proin -567174605,felis sed -330536100,cursus vestibulum proin eu -150214463,leo rhoncus -546553981,lectus in est risus auctor -622297762,magna ac consequat -815652115,quam sollicitudin vitae -360514600,diam -929168597,rutrum nulla tellus -273904312,nam nulla integer -526585073,condimentum neque sapien placerat -674689912,nulla -101853803,sed vel -925040636,praesent lectus vestibulum -138997073,id sapien in -417650394,morbi porttitor lorem -933570818,non mattis pulvinar nulla pede -548757852,nascetur ridiculus mus -251217445,justo etiam pretium iaculis justo -751006683,quam -777992730,sem -435111494,faucibus orci -634491827,ligula suspendisse -180994981,nullam molestie nibh -141072787,risus praesent lectus vestibulum quam -711387241,tellus in sagittis dui -307233834,ligula vehicula -197949545,dignissim vestibulum vestibulum -202201360,ac -242144669,arcu libero rutrum ac -121490976,eleifend luctus ultricies eu nibh -570678540,sed sagittis nam congue risus -572218071,mauris lacinia sapien quis libero -505250102,morbi vel lectus -449069634,diam -940077101,luctus tincidunt -119461772,nunc vestibulum ante -686804112,duis -379428309,sem fusce consequat nulla nisl -310615584,tellus semper -946460769,imperdiet -578850171,erat quisque -506484957,convallis tortor risus dapibus augue -573915022,vivamus vel nulla eget -320183079,aliquam lacus morbi -399615996,luctus nec molestie sed -629475095,magna at -963435759,tortor duis mattis -171464383,etiam -764448316,vehicula consequat morbi a ipsum -718512560,parturient montes nascetur ridiculus -750783000,aliquam augue quam -953556141,porttitor lacus at turpis -152956692,morbi non -687916228,auctor sed tristique -949801400,mauris eget massa tempor -546494601,congue diam id ornare -549344699,eros viverra eget congue -509569588,lacus -225892637,vel nulla eget eros elementum -663180451,tincidunt ante vel -799257852,luctus et -961863978,scelerisque -803576968,pellentesque at nulla suspendisse potenti -801585893,ut ultrices vel augue vestibulum -816725017,nulla suspendisse potenti -974195618,est et tempus semper -580447856,eu tincidunt in -964337945,tristique in tempus sit amet -544777449,eget eleifend -230549629,hendrerit at vulputate -545296026,non -813881053,amet -819164367,integer aliquet massa id lobortis -558821372,libero nam -323092267,ridiculus mus -791785935,etiam faucibus -799969274,ut nulla sed -328611351,et -202089257,nulla dapibus -269082258,vulputate vitae nisl aenean lectus -135576980,mus etiam vel augue -925150948,in hac habitasse -397180477,sapien ut nunc vestibulum ante -885322576,blandit mi in -813277245,sit amet eros -799750288,morbi vestibulum velit id -225032249,sit amet justo morbi -666382618,in felis eu sapien -368115450,augue aliquam erat -292569097,maecenas ut -943384904,in tempus -912101595,quam turpis adipiscing lorem vitae -604780363,interdum in ante -422282416,nunc donec quis -270099491,luctus et ultrices -216544815,nec molestie sed justo -567562212,augue vestibulum -583771343,tincidunt eu felis fusce posuere -836782446,eget massa tempor convallis -336563053,adipiscing -183690096,nunc vestibulum ante -345900431,ipsum aliquam non -397121592,aliquam lacus -897931286,mattis odio donec vitae -985312436,primis -428071210,id nisl venenatis -665002050,id justo sit amet sapien -820671154,urna -727715298,justo morbi ut odio -811706869,arcu sed augue -406049102,vitae consectetuer eget rutrum -725407772,pede libero quis -674137691,et magnis -758828387,risus semper porta -790255816,turpis donec posuere metus -425814466,odio donec vitae -852250348,nec dui luctus rutrum nulla -623649304,massa volutpat convallis -707607947,aliquam non mauris morbi non -802216078,vitae nisi -575336614,semper rutrum nulla nunc purus -616962517,quam fringilla -956210796,turpis adipiscing -601961493,nisl duis ac -603831792,non sodales -339189494,ac -493103046,sit -327703220,in porttitor pede -205963147,lectus in quam -559058826,id consequat in -872810289,est congue elementum -832398535,at -697393010,vitae -382513355,quisque ut erat curabitur -244083834,posuere cubilia curae duis faucibus -352985333,consectetuer adipiscing -504437823,ante -898550291,justo lacinia eget tincidunt eget -131044621,congue vivamus metus -916599905,luctus et -906303754,primis in faucibus orci luctus -402499384,proin at turpis a -627518714,mi in porttitor -627106521,curae duis -235708625,tortor risus dapibus augue -823178472,turpis a pede -674608600,neque vestibulum eget vulputate ut -354643003,parturient montes nascetur ridiculus mus -796264937,porta -421913609,morbi non -696015108,nulla integer pede justo lacinia -794812107,viverra -545117212,sed -993421845,nibh -240466319,purus eu magna -380150979,feugiat et eros -772716870,habitasse platea dictumst -925098950,eget eros -564563702,ut -485186280,non quam nec dui -352043845,orci luctus et ultrices -369793758,luctus et ultrices posuere cubilia -359465666,vel -654177324,pede ac -373063230,porttitor id consequat -723014480,sapien sapien non -175831829,ac -323187119,malesuada in imperdiet -267582075,justo maecenas rhoncus aliquam lacus -678155449,id massa id nisl venenatis -501429797,velit -508738373,donec posuere metus vitae ipsum -322953861,nec -260926142,a suscipit nulla elit -420794641,vitae -895977382,rhoncus sed vestibulum -902532000,proin risus praesent lectus -565520052,pulvinar nulla -211287138,sapien dignissim -715563581,ultrices aliquet -109352238,dolor quis odio -634226982,in blandit ultrices enim lorem -434401213,tincidunt eu felis fusce -225847684,nulla sed vel -930035450,sit amet erat nulla -444644603,posuere cubilia curae mauris -100650996,nisl nunc rhoncus dui -696460385,nisi -857831127,eget vulputate -780472111,volutpat erat quisque erat eros -664487249,in magna bibendum -493178902,at -781794450,in congue -672665563,luctus et ultrices -572534743,aliquam augue quam sollicitudin -115325748,cursus vestibulum proin -843391043,odio curabitur -343104146,imperdiet nullam orci pede venenatis -692320484,placerat ante nulla justo -516272518,leo odio condimentum -215265928,massa id nisl venenatis lacinia -650039423,maecenas tincidunt lacus at -637464362,ac enim in tempor -569045753,at -842109397,posuere cubilia curae nulla -290681974,dui nec -179930839,dapibus dolor vel est donec -154788330,quis libero nullam -373670053,a -423108747,platea dictumst aliquam augue -138277831,nulla tellus in sagittis dui -902032788,in -613882622,ligula suspendisse -999210030,orci vehicula -288313642,tellus -921204221,vestibulum eget vulputate ut -552092841,lobortis convallis tortor risus dapibus -330359197,sem duis -494972337,erat eros -251506227,leo odio condimentum -878640239,orci -211016135,est congue elementum in hac -266278927,lobortis -670812840,phasellus id sapien in sapien -392653996,vestibulum rutrum -496352302,primis -146923821,tempus vivamus -942531335,eleifend -409532528,rutrum nulla nunc purus phasellus -971647881,potenti -340882551,magna vestibulum aliquet -216171648,nulla mollis molestie -595988879,ligula vehicula -607415136,pretium quis -282982632,sit amet -188995752,bibendum morbi non quam nec -408439619,non sodales sed tincidunt -402579840,quam sapien varius -124779681,vivamus in -370080289,nisi -138101271,adipiscing elit proin interdum mauris -510883626,ac -481136018,morbi non lectus aliquam sit -948970226,luctus tincidunt nulla mollis molestie -170063109,vel ipsum -789906127,eget congue eget -351699081,nisl aenean lectus -405967463,orci pede venenatis -118424815,sed magna at -817419752,platea dictumst morbi vestibulum velit -701142847,nisl nunc nisl duis -159723499,eget eleifend luctus ultricies eu -317016234,faucibus orci luctus et -814182084,enim blandit -652900591,consequat in consequat -783274544,at nibh in -863343094,at nibh -304625391,sapien arcu sed -422278237,suscipit nulla -523801794,pretium -177890905,a -750870268,ac enim in -606058712,in faucibus -267030828,velit vivamus vel -505012111,accumsan odio curabitur convallis -727539452,amet sem fusce consequat -203720897,massa quis augue luctus -603097609,orci mauris lacinia sapien quis -999650571,elementum ligula -719478427,eget tincidunt eget tempus vel -404477242,augue vel accumsan tellus nisi -986031609,habitasse platea dictumst -986087444,venenatis -978546867,erat eros viverra -483340383,ac neque duis bibendum -547334052,neque -694304611,integer aliquet massa -333956470,eget congue -315570589,est congue -346561735,lorem -572469222,mauris laoreet ut rhoncus -655944609,ut nunc vestibulum -688588792,odio -684694065,sem duis aliquam convallis nunc -734779696,aliquam erat -740055870,non ligula pellentesque -768899766,ipsum dolor -463072334,tempus vivamus in felis eu -252761005,nulla dapibus dolor vel est -702767330,integer tincidunt -986221086,et ultrices posuere cubilia curae -263217996,lacinia sapien quis libero -726317977,ante -124814961,dis parturient montes nascetur ridiculus -272685600,lorem vitae mattis nibh -120036155,id ligula suspendisse ornare consequat -374407143,hac habitasse platea -693684762,ullamcorper purus sit amet -141427937,velit -836865358,mauris eget massa tempor convallis -391873906,odio condimentum id luctus nec -443382098,libero -869823767,donec ut dolor morbi vel -987515000,dictumst -547165829,posuere nonummy integer non velit -555923865,amet eros suspendisse accumsan tortor -128384443,magna -116600899,libero nullam sit amet -100870873,ultrices vel augue vestibulum ante -248087183,morbi vestibulum velit id -551450047,diam vitae quam suspendisse potenti -298820304,penatibus et magnis dis -707290235,aliquet pulvinar sed -512581817,tellus nisi eu orci mauris -660023357,cursus vestibulum proin eu -474262252,odio cras mi pede malesuada -660178017,at velit eu -123563806,nulla justo aliquam quis -788248902,ut ultrices vel augue vestibulum -945861508,diam cras pellentesque volutpat -135668194,sit amet -713193620,sit amet eros suspendisse -512480138,eu est congue elementum -309631185,purus -430727231,cursus id turpis integer -429589843,blandit -715395030,feugiat -926547019,eget -552344167,pulvinar lobortis est -837583281,integer aliquet -789306925,suscipit nulla elit -997393221,habitasse platea -600795742,dolor sit -931522130,sapien -608577245,proin at turpis a -795111074,quisque -985093634,risus semper porta volutpat -697232021,libero nam dui -799046137,morbi non quam -727705750,ac -205711689,et magnis dis parturient montes -399119263,suspendisse potenti -899125035,turpis donec posuere metus vitae -556326458,integer -492954330,vestibulum sed magna at -684228382,ligula pellentesque ultrices phasellus -992907159,ipsum integer a nibh -494121341,mattis odio -594878147,integer tincidunt -797206974,vestibulum -880140538,vestibulum sagittis sapien cum sociis -224123784,pulvinar lobortis est phasellus sit -380950101,et tempus semper -250499106,ipsum dolor -664786532,pellentesque quisque porta volutpat erat -271665251,volutpat convallis morbi odio -654946551,eu felis fusce posuere -517813115,ipsum integer a -527285044,varius nulla -893397543,duis mattis egestas -139192853,at nibh -199243813,erat -484192990,phasellus sit amet erat nulla -617114999,justo maecenas rhoncus aliquam lacus -412772940,montes nascetur -498340340,nibh in -702051197,vitae mattis nibh -890827231,dolor quis odio -979852217,duis at velit eu -443745840,sed -204348903,convallis eget eleifend luctus ultricies -338252823,rutrum ac lobortis vel dapibus -211880991,nulla sed -323536140,congue etiam justo -481622439,commodo placerat -352513342,pede -483174167,in -467821328,non interdum in ante -426474730,ultrices mattis -302712759,lacus curabitur at ipsum -965342199,pulvinar sed nisl nunc rhoncus -668604599,lacus morbi -507655934,consequat nulla nisl -772313770,volutpat quam pede lobortis ligula -532953449,at velit eu est congue -720637118,turpis enim blandit mi in -125560308,suscipit a feugiat -718309912,nam congue -357154046,semper porta -707234634,libero nam dui proin leo -909414701,diam -535560692,diam erat fermentum justo nec -645157793,duis bibendum morbi -853220209,dictumst -552515800,massa -935154354,amet nunc viverra -991558171,euismod scelerisque quam turpis adipiscing -417467679,neque -411779329,proin eu mi -430981736,nibh ligula -788213677,nunc commodo placerat -364853378,porttitor pede justo -188313701,donec quis orci eget -483856086,integer -443368483,ut -171521965,nulla sed vel -577740624,id consequat in consequat -668752851,nunc purus phasellus in -318942439,quis turpis sed -990003197,elementum -883249424,suspendisse potenti nullam porttitor -723111681,viverra eget congue eget -506334888,leo maecenas pulvinar -542911220,turpis -216560345,justo lacinia eget -416297441,nunc vestibulum ante -761335643,tincidunt eu -883524072,pretium iaculis diam erat fermentum -715677303,habitasse platea dictumst aliquam -851270439,quis tortor id nulla -328825651,bibendum -427809297,mattis egestas -247825681,nulla tellus in sagittis -515552414,sollicitudin -878540296,suscipit a -885714616,suspendisse accumsan -876516251,cubilia curae -310798573,dui nec nisi volutpat eleifend -484828016,ante ipsum primis -891715702,proin -267589254,commodo placerat praesent blandit nam -601748609,in purus -135938718,quisque arcu -384679617,consectetuer adipiscing -628214692,erat fermentum justo nec condimentum -402188110,malesuada in imperdiet -951789527,augue quam sollicitudin vitae -608315312,nulla nunc purus phasellus in -336797998,curae duis -841487208,ipsum primis in faucibus orci -418065407,sem fusce consequat nulla nisl -987840632,lacinia nisi venenatis tristique fusce -983469018,duis mattis egestas metus -238923172,auctor gravida sem praesent -758700355,luctus et ultrices -877689028,pharetra magna vestibulum -671896735,luctus -300707493,molestie hendrerit at vulputate -849623881,posuere cubilia -757816235,phasellus -145251998,curabitur -359461458,arcu libero rutrum ac lobortis -537818112,pretium quis lectus suspendisse potenti -884636420,tortor risus dapibus -921792738,fermentum donec ut mauris -262525004,cras mi pede malesuada in -859759258,diam cras -878485142,dolor quis odio consequat varius -396114155,pulvinar nulla pede -377212901,sapien ut nunc vestibulum ante -939409377,lobortis convallis -446358848,vitae consectetuer -797661049,quis libero nullam -806631176,rutrum ac lobortis vel dapibus -160572194,maecenas -395913173,tincidunt nulla mollis molestie -926827365,placerat ante nulla -335246692,ultrices erat tortor sollicitudin mi -236588729,in quis justo -344615611,nulla pede ullamcorper -505709581,dolor sit amet consectetuer adipiscing -289952759,nulla nisl nunc -337903408,odio -694667297,pede ullamcorper augue -963968065,sapien -164193513,sollicitudin mi sit amet -259564968,id consequat -719349205,magnis dis parturient montes nascetur -776343517,potenti nullam porttitor lacus -646187664,fermentum donec ut mauris eget -475007295,scelerisque mauris -988352472,dapibus at diam nam tristique -990041386,potenti in -748236390,dui vel nisl duis ac -613127640,commodo placerat -894640011,nunc rhoncus dui -506805412,turpis -666819148,at nunc commodo -140060464,sed -747294758,sapien placerat ante -928617042,gravida sem praesent id -667611221,id ornare imperdiet -690292768,curabitur in libero ut -482658102,consequat -457321543,quis turpis -930638989,dui nec nisi volutpat eleifend -312633402,donec ut mauris -310907578,venenatis -221910152,fermentum justo -200720520,sed -709763168,rhoncus dui vel sem -434424390,semper est quam pharetra magna -642193623,vel -269105865,tortor -569806979,lobortis ligula -251429762,amet lobortis sapien sapien -358333209,interdum eu tincidunt in leo -601289581,semper sapien -405873984,velit nec -509142783,semper interdum mauris ullamcorper -381356677,porttitor lacus at turpis donec -140012637,sagittis sapien cum sociis -942641820,condimentum id -239589692,enim leo rhoncus -257488855,enim leo rhoncus sed vestibulum -705328790,duis mattis egestas metus aenean -495575545,nonummy integer non -672855988,nunc donec quis orci -898958231,quisque porta volutpat erat quisque -366802906,nulla justo aliquam quis -591950199,eget semper rutrum nulla -681732848,duis aliquam -839962857,tortor risus dapibus -908221229,in -611236430,non -322429103,vel enim sit amet -327145038,maecenas rhoncus aliquam lacus morbi -636139909,blandit non interdum -156437620,nibh -537800662,turpis -220449006,lectus suspendisse potenti in -452207963,hendrerit at vulputate -336171736,augue -163139736,eu -668512299,curae -190495034,consequat dui nec nisi volutpat -389137943,eros viverra -412107282,ante vel ipsum praesent -326481936,tincidunt -887809220,venenatis -136989271,eros elementum pellentesque quisque porta -615973060,sapien -364954476,vulputate vitae -193122122,nisi nam ultrices libero -624261939,ultrices enim lorem -645177347,eleifend quam a odio -145434589,orci mauris -359123729,metus sapien ut nunc vestibulum -806440181,elementum eu interdum eu -577373873,eget tincidunt eget -542775029,dictumst maecenas ut -325867678,neque libero convallis -516282858,massa tempor convallis nulla -579033069,erat -542943423,eget -905015502,lacus purus -259861370,dui vel nisl -998172842,nullam -839112167,porta volutpat -695818679,condimentum -911414733,fringilla -504796223,dignissim vestibulum -596973156,eros suspendisse accumsan tortor -695344504,tempor convallis nulla neque -608774015,cubilia curae -531598529,orci pede venenatis non -679515240,donec posuere metus vitae -794810995,nibh in quis justo -495566419,leo pellentesque ultrices mattis odio -273982389,libero nullam -376744719,semper est -204519294,vel augue -540789568,vitae ipsum -825650337,consequat dui nec nisi -164553322,volutpat eleifend donec -893682801,praesent blandit lacinia erat vestibulum -736216307,posuere cubilia -115282303,luctus et -661424714,nulla nisl nunc nisl -886876173,eget congue eget semper -797627546,blandit non interdum -248136546,ornare -858063350,quam a odio in hac -518144908,dui proin leo odio porttitor -717503635,mauris -679810030,condimentum -573681329,erat id mauris vulputate -324588746,nulla eget -263724182,consequat -228651480,ut massa volutpat convallis -569344327,sit amet nunc viverra dapibus -727914562,in faucibus orci luctus -410728498,nisl duis -299351824,leo odio condimentum -743594112,quis turpis -740220472,habitasse platea dictumst aliquam augue -494228254,convallis morbi -581521325,lorem -551837749,diam in magna -831383506,enim -812804966,ligula sit -634390750,amet nunc viverra dapibus -888340442,phasellus sit amet erat -615480440,vulputate elementum -876777532,rhoncus -655200339,nunc rhoncus dui vel -895141500,dolor sit amet -152986767,consequat ut nulla -929079233,est et tempus semper -943661188,ac diam cras pellentesque -577208040,nisl -613905284,nisl aenean lectus -411698041,tempor convallis nulla -662632622,suspendisse potenti in -320822367,venenatis non -611849575,nam tristique -335999160,ridiculus mus vivamus vestibulum -918078673,nisl nunc nisl duis bibendum -934783003,sed magna at nunc -555635725,amet -955068768,volutpat convallis morbi odio -341961733,suspendisse -818937991,justo etiam pretium iaculis -595241729,donec semper -848625131,diam cras pellentesque volutpat -728249561,aliquam -579547111,in est risus auctor sed -738396516,platea -622466639,enim leo rhoncus -759610120,in lacus curabitur at -873310007,nibh ligula nec -527976824,diam neque vestibulum eget vulputate -282722646,tortor -864835969,sed tincidunt eu felis fusce -183787512,justo in blandit -884263999,platea dictumst -277468483,porttitor lorem -467575123,blandit nam -170226447,nulla ac enim in -383625565,dui maecenas tristique est et -712194582,turpis a pede posuere -926772912,vel dapibus -647682961,sed vel enim -940754455,sed tristique in tempus -212337805,sapien cursus vestibulum -313972110,maecenas leo odio condimentum -211141998,urna ut tellus nulla -216423979,nam congue risus semper porta -136283888,eget tempus vel -806500236,pellentesque -974023724,tempus vivamus in felis eu -330281452,aliquam augue quam sollicitudin vitae -519142223,nunc nisl duis -517073898,cubilia curae donec pharetra -327819176,justo in hac habitasse -867382836,pellentesque volutpat dui maecenas -637153152,eu est congue -176076412,curabitur -683990873,rutrum nulla -938139253,odio curabitur -119108048,non mattis pulvinar nulla pede -438282765,in libero ut -418533359,sapien placerat -628186266,sodales sed tincidunt eu felis -452123284,vestibulum -301823843,leo -435905846,praesent blandit nam nulla integer -994258868,in sagittis -503721403,ut at dolor quis odio -992002423,dapibus at diam nam tristique -839022252,massa quis augue -983585751,orci eget orci vehicula condimentum -311280848,imperdiet et commodo vulputate -638322643,eleifend quam a odio -924603203,potenti in eleifend quam a -758760629,imperdiet sapien urna pretium nisl -738816555,justo morbi -109096518,lorem ipsum dolor sit amet -863392671,sollicitudin -155698335,a ipsum integer a nibh -844157267,pede lobortis ligula sit amet -454609028,justo etiam pretium iaculis justo -835854578,ultrices enim lorem ipsum dolor -767419552,augue vel accumsan -670282990,posuere metus -422965679,dolor -873442940,vitae ipsum aliquam non -778639313,etiam -826991461,pede ullamcorper augue a suscipit -627645989,montes nascetur ridiculus mus -245131529,non interdum in ante vestibulum -149501024,turpis elementum ligula vehicula consequat -772089024,pretium quis lectus suspendisse potenti -679779387,sociis -590701488,sit amet -115768037,diam -684437666,lacus morbi -595786263,sagittis nam -500255591,eget -430062072,fusce -901127037,nulla mollis molestie lorem -216233201,justo in hac habitasse -238959059,ornare consequat -163269286,etiam justo -641731695,justo etiam -843634910,vel augue vestibulum rutrum -401159942,nunc vestibulum ante ipsum -816507402,primis -962248851,mi nulla -123534730,pellentesque ultrices phasellus id sapien -195869669,sapien cursus vestibulum -878553608,augue vestibulum -721416772,quis turpis sed ante vivamus -865141777,ante -834467152,pede morbi -395628345,euismod scelerisque quam -817906043,ac nulla sed vel -485436011,ac -994960363,volutpat convallis morbi odio odio -181955069,et eros -762258168,potenti cras in purus -340450633,suspendisse ornare consequat lectus in -755228422,ac -634831107,accumsan tellus nisi -875157607,elementum ligula vehicula -213025751,praesent id massa id nisl -561770418,id nisl -290898175,vestibulum sagittis sapien cum -823967664,curabitur in -844297074,ultrices -820285930,quam -411890273,in hac -658712075,cubilia curae donec -886052378,a pede posuere nonummy integer -988371559,in -146172148,vestibulum ante ipsum -163016505,malesuada in -471932195,varius nulla -865928093,odio condimentum id luctus -593753173,odio condimentum id -209841960,ultrices posuere cubilia -108243006,a pede -462446838,velit eu est congue elementum -149072150,tempor convallis nulla neque libero -637374165,posuere -432270449,bibendum morbi non -386232982,felis donec semper sapien -857302739,sit amet lobortis -291336808,penatibus et magnis dis parturient -324394334,arcu sed -709367585,erat -847248498,id lobortis convallis tortor risus -371241956,quisque -186235108,dolor sit amet -348991042,integer tincidunt ante -680616068,molestie -639951539,at feugiat non pretium -360821375,cum sociis natoque -311306972,lectus in est risus -163252586,in hac habitasse -813581781,justo -416364390,rutrum -401549431,dui proin leo odio -447440253,nunc donec quis -675813411,quis tortor id -587330763,imperdiet nullam orci -331173642,hac habitasse platea dictumst -805395538,elementum ligula vehicula -818411463,tristique tortor eu pede -995476765,vivamus in -941968176,ac consequat -820391838,morbi non lectus aliquam sit -278104608,quisque porta -592199181,dui nec nisi volutpat -801736599,donec pharetra -912380435,turpis -148750733,vestibulum velit id pretium -207085212,erat id mauris vulputate -844472162,dictumst morbi -392378567,luctus tincidunt nulla mollis -774701980,dui vel nisl duis -425106318,ridiculus mus -691641084,ac -280199068,justo sit -174232188,maecenas tincidunt lacus at velit -244113842,enim sit amet -915568941,eleifend quam a -511374965,sit -401253993,augue vel -743568942,aliquam convallis nunc proin at -607601406,a -826353395,quis augue luctus tincidunt nulla -789849127,at nulla suspendisse potenti cras -812799966,interdum eu -802158247,a pede posuere nonummy -438460245,quis orci eget orci -954503390,quis turpis -313588657,duis consequat dui nec nisi -348665072,duis bibendum -499156679,faucibus cursus urna ut -334408583,vestibulum ac -483956965,turpis sed -156925860,ut -665827316,parturient montes -896068223,augue aliquam erat volutpat in -684943838,ut nunc vestibulum ante ipsum -537206216,augue vel -598381583,nec condimentum neque sapien -812743233,etiam faucibus cursus -169387137,imperdiet sapien urna pretium nisl -536193318,fringilla rhoncus mauris enim -635476602,ut massa quis augue -932261902,eget nunc donec quis -200112420,scelerisque mauris sit amet -818827228,sem mauris laoreet ut -164017145,porttitor lacus at turpis donec -857694064,donec dapibus duis at -978748688,mauris eget massa tempor -674570141,etiam justo etiam pretium iaculis -144400230,proin risus praesent lectus vestibulum -572996919,et eros -960957343,potenti cras in purus eu -288581288,sollicitudin vitae consectetuer eget -871679778,blandit lacinia erat vestibulum -690397090,dui luctus -665956883,lacus curabitur at ipsum ac -543046465,convallis -982352529,vel dapibus at diam nam -788900742,ante ipsum primis -249995944,ultrices posuere cubilia curae -738867421,sit amet sem fusce consequat -343262252,dis parturient montes nascetur -755323277,gravida sem praesent -832204565,aliquet maecenas leo -753392400,sem -209039188,turpis a pede posuere nonummy -342658442,orci mauris lacinia sapien quis -207875460,ante ipsum primis in -262033654,metus sapien ut -961104742,amet consectetuer adipiscing elit proin -228790534,at nibh -995695519,ultrices vel augue vestibulum ante -467790777,adipiscing elit proin -407206441,dui maecenas tristique est -928667300,rhoncus aliquet pulvinar -216695753,phasellus sit -985823804,justo maecenas rhoncus aliquam -517824935,nisi eu orci -692217402,suspendisse potenti -651489272,vestibulum velit id pretium -608779350,aliquet -301176585,cursus vestibulum proin -632178636,lobortis vel dapibus -752767844,velit -824255982,dolor sit amet consectetuer -678134304,sem mauris laoreet -397551651,velit id pretium iaculis diam -166188031,dui proin -617334271,quisque arcu libero -415018514,ut massa -835090140,quisque -618648227,luctus et ultrices posuere -641343527,potenti in eleifend quam a -573096073,vestibulum quam -688777638,aliquet ultrices erat tortor -237354067,justo -413283441,viverra pede ac diam cras -877362142,adipiscing elit proin -203684975,diam erat -793760253,lorem id ligula suspendisse -974274636,libero nullam -471565695,in -406503769,tellus -616195208,non mauris morbi non -968469917,ac nulla -408894918,dui vel nisl duis -967324196,erat id mauris -270329924,in felis eu -755398908,porttitor lorem -286808627,id turpis -576891419,blandit nam -111610797,pulvinar -725976420,id consequat -814042913,facilisi cras -935436640,potenti cras in purus eu -767554988,varius nulla facilisi cras non -586166201,vestibulum ante ipsum primis -601967247,scelerisque mauris sit amet -199891963,sed ante vivamus tortor duis -681658704,varius ut blandit -884721176,est phasellus sit amet erat -992166131,aliquam lacus morbi -141829527,lacus at velit vivamus -132111273,pede venenatis non -600257973,vestibulum sed -102043103,arcu libero -490689099,in faucibus orci -663564465,pede -444308883,maecenas -121877391,consequat varius integer ac leo -450134409,congue eget semper rutrum nulla -166533447,penatibus et -120736974,ipsum primis in -809724100,sit amet consectetuer adipiscing -847309429,id massa id -698709234,amet lobortis sapien -493567130,erat tortor sollicitudin -276556021,lorem -315672350,luctus et ultrices posuere -982565820,erat fermentum justo -768694990,ipsum primis in -152575110,sapien in sapien iaculis -954262445,bibendum morbi non quam -182019881,aliquam convallis nunc proin at -310190273,posuere cubilia curae -922793517,consequat -628379252,nisi at nibh -619544093,viverra pede -380920244,sem praesent id -260924967,cursus vestibulum proin -643671862,duis faucibus accumsan odio -270126296,ultrices -854835885,dapibus augue vel accumsan tellus -178307743,hac habitasse platea -257879206,ligula pellentesque ultrices phasellus id -977915466,cubilia curae nulla -747585057,integer non velit donec diam -980170267,consectetuer adipiscing -806233471,etiam vel augue vestibulum -267491906,augue quam sollicitudin vitae -550555158,eu nibh quisque id -843882065,libero ut massa volutpat -851984233,in -242815066,dui vel sem -627029329,eu mi -261465366,ipsum -324487007,commodo placerat -180873626,sapien placerat ante nulla justo -204970501,viverra -848933100,aliquam -864594887,gravida sem -579186977,nunc viverra dapibus -758979788,pulvinar lobortis est phasellus -461249471,ut -791407309,blandit mi in -798025557,turpis integer -706819934,ultrices posuere cubilia curae -641444899,sed augue aliquam erat -473369614,tortor id nulla ultrices -236842987,posuere -854695480,elit ac nulla sed vel -600613809,fringilla rhoncus mauris enim leo -881447966,phasellus -918636886,quis justo maecenas rhoncus aliquam -561326791,odio donec -626616014,lorem vitae mattis -694149717,nulla -521692518,iaculis congue vivamus -384250670,ultrices mattis odio donec vitae -186561797,aenean lectus pellentesque -497803206,augue -104763456,ultrices enim lorem ipsum -708789137,fermentum donec ut -373539387,elit -827561567,morbi non -905197322,eu mi -438344749,in libero ut massa volutpat -930533502,curabitur gravida nisi at nibh -940929395,erat nulla tempus vivamus -262835699,etiam vel augue -340967597,in est -897363374,vulputate elementum nullam -337486490,egestas metus aenean fermentum -500330348,semper -264536987,felis -566188979,nisl -993334510,eget -542449434,nulla ultrices aliquet maecenas leo -338135356,id lobortis -381471551,in felis eu -713044469,non -712099583,eget massa tempor -192073149,libero nam -606899646,et magnis dis parturient montes -457874104,nulla mollis molestie lorem quisque -916043605,odio justo -133436984,nibh in lectus pellentesque at -259748348,donec ut -734260430,tincidunt -483047554,proin leo -326738688,nibh -998593302,pede ullamcorper augue a suscipit -260666005,mauris vulputate elementum nullam varius -891694531,quis orci nullam molestie -356288635,id nisl venenatis lacinia aenean -113644770,etiam -378875811,in libero ut massa -905793522,condimentum id luctus -404245440,ipsum dolor sit -246835477,donec odio -420597179,non -971520486,quam -402633970,integer pede justo -195350920,eros -814286183,mus vivamus -409540968,luctus et ultrices posuere -236972569,vestibulum sit amet cursus -986173972,risus praesent lectus -174795432,mattis -680749525,justo -186921337,leo odio condimentum id -899382956,vitae ipsum -314996904,nisl nunc -447199123,justo nec condimentum -315233127,tellus in sagittis dui vel -226912589,nulla integer pede justo -947248936,sed -967393566,auctor sed -308392295,est -104399967,sapien dignissim vestibulum vestibulum -305252304,dapibus -717184768,ut at dolor -747214223,vestibulum ante ipsum primis in -635192167,ac nulla -262591642,id luctus nec molestie sed -441266442,sed interdum venenatis turpis -345154012,eros vestibulum ac est -890908153,nunc -976916475,integer -841899134,cursus id turpis -600004013,accumsan odio curabitur convallis duis -925004283,neque sapien placerat ante nulla -322695013,libero nullam sit amet turpis -166200955,diam -624112845,pellentesque -985147991,in purus eu -464468353,aliquam quis turpis eget elit -431680418,morbi -910562941,tincidunt in leo maecenas pulvinar -108059736,lacus at turpis donec -775447699,integer aliquet massa -217975494,amet nulla -605705234,maecenas rhoncus -238864075,libero ut massa volutpat convallis -980367138,sit amet eros suspendisse -467735406,volutpat sapien -591815497,mauris lacinia sapien -874834541,amet consectetuer adipiscing -796716857,nisl venenatis lacinia aenean -870042229,tortor duis mattis egestas -980783918,quis justo maecenas rhoncus -774014144,in tempor turpis nec -567233092,elementum pellentesque quisque porta volutpat -278603210,ut suscipit a feugiat -883661882,amet consectetuer -393261847,vehicula -661099783,quis orci -283514263,nisi -873482086,nunc -579958311,massa -606885716,diam in magna bibendum imperdiet -782147042,fermentum justo nec condimentum -126562432,porta volutpat -137471452,mauris non -695992892,eu tincidunt in leo maecenas -220096230,in purus eu magna vulputate -598380112,aliquet maecenas -442268241,mi sit amet lobortis -712887563,mattis odio donec vitae nisi -690846895,vestibulum ante ipsum primis -717939629,sodales sed tincidunt eu felis -874422690,parturient -925846709,at -385926978,praesent lectus vestibulum quam sapien -823447780,nec nisi volutpat -868422109,ridiculus mus etiam -838427390,etiam faucibus -217774200,aliquet pulvinar sed nisl nunc -311243069,morbi odio odio elementum -898352637,justo eu massa -517075983,nec dui -422797680,vitae mattis nibh ligula nec -573179031,nam -937093360,amet diam in magna -585559451,mauris viverra -827742979,augue a suscipit nulla -415035719,maecenas rhoncus -856247669,lorem integer tincidunt ante vel -250998849,massa tempor convallis -738698395,erat volutpat -988835851,lacus at turpis -974128004,cras pellentesque volutpat dui -228751730,justo aliquam -997530356,vestibulum vestibulum ante -834484822,leo -445666009,nisl ut volutpat -839277063,faucibus orci -582012527,lobortis vel dapibus at diam -251747201,justo lacinia eget -744472189,tellus nulla -479326704,amet eros suspendisse accumsan -985804521,consequat nulla nisl nunc -683927024,nec -367300560,volutpat -416760216,nonummy maecenas tincidunt lacus at -376868642,sit amet consectetuer adipiscing -922195824,vestibulum sagittis sapien -190614183,ante nulla justo aliquam quis -836677567,interdum venenatis turpis enim -788581285,primis -190541681,sapien arcu -428099369,duis bibendum -483742808,ut dolor morbi vel -996442115,felis eu sapien cursus -819256298,diam vitae quam suspendisse potenti -345974372,fusce consequat nulla nisl -716239929,quam nec dui -751679287,eleifend pede libero -969937195,eu est congue elementum in -112186502,ut massa -194476696,libero nullam -647862240,magna at nunc -212529638,odio justo -399931005,ipsum primis in faucibus -737465756,eget tempus vel -144858254,congue risus semper -895159492,blandit lacinia erat -259731853,ante -252710196,aliquam non mauris -304094365,nunc viverra -234814143,natoque penatibus et -956211343,arcu libero -815268650,ligula in -888033864,justo nec condimentum neque sapien -986117338,amet lobortis -488199921,interdum in ante vestibulum ante -259345382,pretium -411380607,erat vestibulum sed magna -233445630,vestibulum sed magna at -723868263,nulla nisl nunc -961242283,nam tristique tortor eu pede -608952047,nunc donec -639339722,consectetuer eget rutrum at -729782224,quam sapien -193006854,nec -766837591,justo maecenas rhoncus -273407136,at velit vivamus vel nulla -566504975,augue quam sollicitudin vitae consectetuer -143805956,pellentesque ultrices phasellus id -452586192,sem fusce consequat nulla -607669775,a pede posuere -633932950,sit amet consectetuer -688953301,rhoncus -787726346,quisque arcu libero rutrum ac -529296815,nulla -948407358,ipsum -927836750,vitae consectetuer eget rutrum -448111635,nisl -902650800,rutrum nulla tellus in sagittis -883745788,in sagittis dui -687699072,felis fusce posuere felis -470977885,ultrices phasellus id sapien -369050986,ut mauris eget -910029911,eleifend quam -435559074,vivamus vestibulum -354490451,cursus vestibulum -943999286,habitasse platea -527231188,tincidunt eu felis fusce posuere -222451437,sapien quis -104928323,lectus aliquam sit amet -442516790,natoque penatibus et magnis dis -509744869,posuere cubilia curae donec -123706951,id -559312704,vulputate justo in blandit ultrices -186756046,platea dictumst aliquam -462918555,amet consectetuer adipiscing elit -570635346,praesent lectus vestibulum quam -123572421,sit amet consectetuer -675472896,elementum nullam varius nulla facilisi -155425397,nunc -495926807,donec -200465095,volutpat convallis morbi odio -241518266,pellentesque quisque porta -274158853,pretium iaculis diam erat fermentum -573041817,eget tempus vel -634502284,cubilia curae mauris viverra -109016417,blandit mi in -489557161,purus eu magna -169429653,ridiculus -737367903,in -884254540,lobortis ligula sit -382305567,nulla ac enim in -502998194,nam tristique tortor eu -438453994,pede -804575709,vivamus metus arcu -799580863,porttitor id -352489021,nunc purus phasellus -424075397,elit -313602498,vel accumsan tellus nisi -806829738,eget semper rutrum nulla -316779231,ut blandit non interdum -913183907,lectus suspendisse potenti in -578515611,ipsum primis in faucibus orci -144945878,sed interdum -882451218,posuere cubilia curae -916216109,lorem -672961731,id ornare -702920219,nulla dapibus -200317604,consequat lectus in -453821280,sapien placerat ante -799655130,hendrerit at vulputate -854387401,ligula vehicula -969019421,morbi a -561226093,vivamus tortor duis mattis -916663454,proin leo odio -782759853,platea dictumst maecenas ut massa -230559893,sapien placerat -504776585,suscipit nulla elit ac nulla -595871784,sapien a -820151311,vel pede morbi porttitor -279452333,non -312998109,porta volutpat quam -277009208,vitae -876805682,maecenas rhoncus aliquam lacus morbi -367536997,morbi odio odio elementum -956054153,orci nullam molestie -794143521,pede ac diam cras -358324164,quam -886904374,nisi at nibh in -259310420,in sagittis -720044908,nonummy integer -794132825,diam vitae quam -170612699,volutpat -830313678,elit ac nulla sed -757460474,odio donec -360619176,neque -758338552,quisque ut erat curabitur gravida -362959405,dui maecenas -287547903,luctus rutrum nulla tellus in -565018688,eget eleifend -733894846,id consequat in consequat ut -301221465,quam fringilla rhoncus mauris -745292327,sapien cum sociis -449480816,dui maecenas tristique est et -281855651,mauris enim -988396300,fermentum -908608969,in -616063293,vestibulum -481875581,amet consectetuer adipiscing elit -306341858,libero ut massa volutpat -220899511,dolor sit amet consectetuer adipiscing -740081454,vivamus tortor duis mattis egestas -224366136,in faucibus orci -487083156,eget nunc donec -824826009,cum sociis natoque penatibus et -316754517,nisl ut volutpat -420601423,justo etiam pretium iaculis justo -438986839,cubilia curae mauris viverra diam -294644767,parturient -349690883,pede justo eu -793634638,sapien -553303438,ligula sit -904066760,cum sociis natoque penatibus et -117703779,id nulla -959375119,eget congue eget semper -697189721,sem mauris laoreet -991695738,libero convallis -625045276,amet -137297917,duis faucibus accumsan odio curabitur -646844413,donec -422330806,lacus at turpis -115259001,cras non velit nec -384732717,in sapien -954111561,eget -311772544,metus vitae ipsum aliquam non -526089556,scelerisque quam -707223395,cras pellentesque volutpat -849164582,consequat -483778314,in leo maecenas pulvinar -569568920,luctus et ultrices posuere cubilia -668220887,nunc vestibulum ante ipsum -537154673,nunc vestibulum ante -774439823,cras non velit -210868759,potenti cras in purus -942575961,sed augue aliquam erat volutpat -411220442,felis sed interdum venenatis -268014415,sed nisl -689312997,cursus vestibulum proin eu -747656048,dui luctus rutrum nulla tellus -101955563,cursus id turpis -758464794,ac diam cras pellentesque -241841032,morbi vestibulum velit id -349542755,sed -594545903,amet nulla quisque arcu libero -366118294,in congue etiam justo etiam -716539980,in hac habitasse -699188283,nulla suspendisse potenti cras in -874010795,augue luctus -896888302,tincidunt eget tempus -593530805,lacinia nisi venenatis tristique -328646682,nullam orci pede -872358887,erat id mauris -176202868,non mattis pulvinar nulla pede -585003171,sollicitudin mi -407184877,ut massa quis augue luctus -757711987,aliquam non mauris morbi -201555151,donec dapibus duis at -389516933,libero -904790654,lorem vitae mattis nibh ligula -752278896,sed accumsan felis ut at -308607362,ullamcorper augue a suscipit -467634172,erat fermentum justo nec condimentum -878043634,vel augue vestibulum ante ipsum diff --git a/examples/others/book_store/main.c b/examples/others/book_store/main.c deleted file mode 100644 index e9653bd..0000000 --- a/examples/others/book_store/main.c +++ /dev/null @@ -1,180 +0,0 @@ -// Welcome to the book store - -#include -#include -#include -#include -#include -#include "macro_collections.h" -#include "book.c" -#include "random.c" - -COLLECTION_GENERATE(LIST, l, list, , , book *) -COLLECTION_GENERATE(LIST, il, intlist, , , int) -COLLECTION_GENERATE(QUEUE, q, queue, , , book *) -COLLECTION_GENERATE(TREEMAP, map, map, , int, char *) -COLLECTION_GENERATE(TREESET, set, set, , , char *) - -list *load(void); -void shuffle(list *l); - -int intcmp(int a, int b) -{ - return a - b; -} - -int chrcmp(char *a, char *b) -{ - return strcmp(a, b); -} - -int main(int argc, char const *argv[]) -{ - srand((unsigned)time(NULL)); - - // Load our books from database (csv). - list *books = load(); - - // Shuffle our books. - shuffle(books); - - // Last added books are kept here. These are the 'featured' books. - queue *shelf = q_new(10); - - // Books in our library. Using this to fast lookup our books. - map *library = map_new(intcmp); - - // Calculate how many unique book titles - set *counter = set_new(chrcmp); - - // Add everything to its place. - FOR_EACH(l, list, books, { - book *value = l_iter_value(&iter); - - // Keep the last added elements - if (q_count(shelf) > 7) - { - q_dequeue(shelf); - } - - q_enqueue(shelf, value); - - map_insert(library, value->isbn, value->name); - set_insert(counter, value->name); - }); - - printf("Library Size: %d\n", map_count(library)); - printf("Unique book titles: %d\n\n", set_count(counter)); - printf("Showcase Books:\n"); - FOR_EACH(q, queue, shelf, { - book *value = q_iter_value(&iter); - printf("[ %d : %-45s ]\n", value->isbn, value->name); - }); - printf("\n"); - - set_free(counter); - - int c, isbn; - char buffer[100]; - while (true) - { - printf("\n[0] [ Exit ]\n"); - printf("[1] [ Search by ISBN ]\n"); - printf("[2] [ Search by Name ]\n"); - printf("> "); - scanf("%d", &c); - - if (c == 0) - break; - - if (c == 1) - { - while (true) - { - printf("[0] [ Exit ]\n"); - printf("ISBN:\n> "); - scanf("%d", &isbn); - - if (isbn == 0) - break; - - char *search = map_get(library, isbn); - - if (search == NULL) - printf("No book found\n"); - else - printf("%s\n", search); - } - } - else if (c == 2) - { - printf("Name:\n> "); - fflush(stdin); - fgets(buffer, 100, stdin); - // Remove newline character - buffer[strcspn(buffer, "\n")] = 0; - - intlist *search_list = il_new(32); - - FOR_EACH(map, map, library, { - int key = map_iter_key(&iter); - char *value = map_iter_value(&iter); - - if (chrcmp(buffer, value) == 0) - il_push_back(search_list, key); - }); - - FOR_EACH(il, intlist, search_list, { - printf("[ %d ]\n", il_iter_value(&iter)); - }); - - il_free(search_list); - } - } - - // Free all memory used by struct book - FOR_EACH(l, list, books, { - book *b = l_iter_value(&iter); - - if (b) - free(b->name); - - free(b); - }); - - l_free(books); - q_free(shelf); - map_free(library); - - return 0; -} - -list *load(void) -{ - FILE *fptr = fopen("books.csv", "r"); - - int isbn; - char buffer[1000]; - list *books = l_new(1000); - - while (fscanf(fptr, "%d,%[^\n\r]s", &isbn, buffer) != EOF) - { - book *b = new_book(isbn, buffer); - l_push_back(books, b); - } - - return books; -} - -void shuffle(list *l) -{ - size_t min = 0, max = l_count(l) - 1; - - for (size_t i = 0; i < max; i++) - { - size_t j = randsize(min, max); - book *tmp = l->buffer[j]; - l->buffer[j] = l->buffer[i]; - l->buffer[i] = tmp; - } -} diff --git a/examples/others/book_store/random.c b/examples/others/book_store/random.c deleted file mode 100644 index 31f0f2b..0000000 --- a/examples/others/book_store/random.c +++ /dev/null @@ -1,18 +0,0 @@ -// Random functions -#include -#include - -double rrandom() -{ - return (double)rand() / ((double)RAND_MAX + 1.0); -} - -int randint(int min, int max) -{ - return (int)floor(rrandom() * ((double)max - (double)min + 1.0) + (double)min); -} - -size_t randsize(size_t min, size_t max) -{ - return (size_t)floor(rrandom() * ((double)max - (double)min + 1.0) + (double)min); -} diff --git a/examples/others/for_each.c b/examples/others/for_each.c deleted file mode 100644 index 9cfa5b2..0000000 --- a/examples/others/for_each.c +++ /dev/null @@ -1,135 +0,0 @@ -#include "macro_collections.h" -#include -#include -#include - -// Create containers to use only in this file -CMC_GENERATE_LIST(l, list, int) -CMC_GENERATE_LINKEDLIST(ll, llist, int) -CMC_GENERATE_STACK(s, stack, int) -CMC_GENERATE_QUEUE(q, queue, int) -CMC_GENERATE_DEQUE(d, deque, int) -CMC_GENERATE_TREESET(ts, tset, int) - -int intcmp(int a, int b) -{ - return (a > b) - (a < b); -} - -int main(int argc, char const *argv[]) -{ - // Initialize all of them with an internal capacity of 100 - struct list *l = l_new(100); - struct llist *ll = ll_new(); - struct stack *s = s_new(100); - struct queue *q = q_new(100); - struct deque *d = d_new(100); - struct tset *ts = ts_new(intcmp); - - // Add 20 elements to each of them - for (int i = 0; i < 20; i++) - { - l_push_back(l, i); - ll_push_back(ll, i); - s_push(s, i); - q_enqueue(q, i); - d_push_back(d, i); - ts_insert(ts, i); - } - - // Some extra elements - s_push(s, 21); - q_enqueue(q, 21); - q_enqueue(q, 22); - d_push_back(d, 21); - d_push_back(d, 22); - d_push_back(d, 23); - ll_push_back(ll, 21); - ll_push_back(ll, 22); - ll_push_back(ll, 23); - ll_push_back(ll, 24); - ts_insert(ts, 21); - ts_insert(ts, 22); - ts_insert(ts, 23); - ts_insert(ts, 24); - ts_insert(ts, 25); - - // All CMC_FOR_EACH macros contains three available variables: - // - value : the elements that changes with each iteration - // - index : iteration index (first iteration is 0 and last is count - 1) - // - iter : iterator struct - CMC_FOR_EACH(l, list, l, { - int value = l_iter_value(&iter); - size_t index = l_iter_index(&iter); - if (index == 0) - printf("[ %d, ", value); - else if (index == iter.target->count - 1) - printf("%d ]\n", value); - else - printf("%d, ", value); - }); - - CMC_FOR_EACH(s, stack, s, { - int value = s_iter_value(&iter); - size_t index = s_iter_index(&iter); - if (index == 0) - printf("[ %d, ", value); - else if (index == iter.target->count - 1) - printf("%d ]\n", value); - else - printf("%d, ", value); - }); - - CMC_FOR_EACH(q, queue, q, { - int value = q_iter_value(&iter); - size_t index = q_iter_index(&iter); - if (index == 0) - printf("[ %d, ", value); - else if (index == iter.target->count - 1) - printf("%d ]\n", value); - else - printf("%d, ", value); - }); - - CMC_FOR_EACH(d, deque, d, { - int value = d_iter_value(&iter); - size_t index = d_iter_index(&iter); - if (index == 0) - printf("[ %d, ", value); - else if (index == iter.target->count - 1) - printf("%d ]\n", value); - else - printf("%d, ", value); - }); - - CMC_FOR_EACH(ll, llist, ll, { - int value = ll_iter_value(&iter); - size_t index = ll_iter_index(&iter); - if (index == 0) - printf("[ %d, ", value); - else if (index == iter.target->count - 1) - printf("%d ]\n", value); - else - printf("%d, ", value); - }); - - CMC_FOR_EACH(ts, tset, ts, { - int value = ts_iter_value(&iter); - size_t index = ts_iter_index(&iter); - if (index == 0) - printf("[ %d, ", value); - else if (index == iter.target->count - 1) - printf("%d ]\n", value); - else - printf("%d, ", value); - }); - - l_free(l, NULL); - ll_free(ll, NULL); - s_free(s, NULL); - q_free(q, NULL); - d_free(d, NULL); - ts_free(ts, NULL); - - return 0; -} diff --git a/examples/others/separate_header_source/Makefile b/examples/others/separate_header_source/Makefile deleted file mode 100644 index d72e379..0000000 --- a/examples/others/separate_header_source/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -CC = gcc -CFLAGS = -Wall -Wextra -INCLUDE = ./ -SRC = ../../../src - -main.exe: containers.o main.o $(SRC)/macro_collections.h - $(CC) $^ -o $@ - -%.o: %.c $(SRC)/macro_collections.h - $(CC) -I $(INCLUDE) -I $(SRC) $(CFLAGS) -c $< -o $@ - -run: main.exe $(SRC)/macro_collections.h - ./main.exe \ No newline at end of file diff --git a/examples/others/separate_header_source/containers.c b/examples/others/separate_header_source/containers.c deleted file mode 100644 index 04a01c5..0000000 --- a/examples/others/separate_header_source/containers.c +++ /dev/null @@ -1,6 +0,0 @@ -#include "containers.h" - -CMC_GENERATE_LIST_SOURCE(il, int_list, int) -CMC_GENERATE_STACK_SOURCE(cs, char_stack, char) -CMC_GENERATE_QUEUE_SOURCE(queue, index_queue, size_t) -CMC_GENERATE_DEQUE_SOURCE(dq, deque, int) diff --git a/examples/others/separate_header_source/containers.h b/examples/others/separate_header_source/containers.h deleted file mode 100644 index c53e400..0000000 --- a/examples/others/separate_header_source/containers.h +++ /dev/null @@ -1,14 +0,0 @@ -#include -#include -#include - -#include "cmc/list.h" -#include "cmc/stack.h" -#include "cmc/queue.h" -#include "cmc/deque.h" - - -CMC_GENERATE_LIST_HEADER(il, int_list, int) -CMC_GENERATE_STACK_HEADER(cs, char_stack, char) -CMC_GENERATE_QUEUE_HEADER(queue, index_queue, size_t) -CMC_GENERATE_DEQUE_HEADER(dq, deque, int) diff --git a/examples/others/separate_header_source/main.c b/examples/others/separate_header_source/main.c deleted file mode 100644 index ce82d86..0000000 --- a/examples/others/separate_header_source/main.c +++ /dev/null @@ -1,264 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include "macro_collections.h" -#include "containers.h" - -double rrandom() -{ - return (double)rand() / ((double)RAND_MAX + 1.0); -} - -int8_t random_int8_t(int8_t min, int8_t max) -{ - return (int8_t)floor(rrandom() * ((double)max - (double)min + 1.0) + (double)min); -} - -size_t random_size_t(size_t min, size_t max) -{ - return (size_t)floor(rrandom() * ((double)max - (double)min + 1.0) + (double)min); -} - -char random_alpha() -{ - const char alpha[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', - 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', - 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', - 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', - 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', - 'Y', 'Z'}; - return alpha[random_int8_t(0, 61)]; -} - -int main(void) -{ - srand((unsigned)time(NULL)); - - struct int_list *list = il_new(10); - - for (int i = 0; i < 100; i++) - { - il_push_at(list, i, list->count == 0 ? list->count : i % list->count); - } - - printf("\n[ "); - - for (size_t i = 0; i < list->count - 1; i++) - printf("%d, ", il_get(list, i)); - - printf("%d ]\n", il_get(list, list->count - 1)); - - il_free(list, NULL); - - list = il_new(10); - - for (int i = 0; i < 10; i++) - { - // Add elements - il_push_back(list, i); - - // Print - if (!il_empty(list)) - { - // Print - printf("\n[ "); - for (size_t i = 0; i < list->count - 1; i++) - { - printf("%d, ", il_get(list, i)); - } - printf("%d ]\n", il_get(list, list->count - 1)); - } - } - - for (int i = 0; i < 10; i++) - { - // Remove elements - il_pop_back(list); - - if (!il_empty(list)) - { - // Print - printf("\n[ "); - for (size_t i = 0; i < list->count - 1; i++) - { - printf("%d, ", il_get(list, i)); - } - printf("%d ]\n", il_get(list, list->count - 1)); - } - } - - il_free(list, NULL); - - list = il_new(1000); - - for (int i = 0; i < 1000; i++) - { - if (i % 2 == 0) il_push_at(list, i, list->count); - } - - // Print all even numbers - if (!il_empty(list)) - { - // Print - printf("\n[ "); - for (size_t i = 0; i < list->count - 1; i++) - { - printf("%d, ", il_get(list, i)); - } - printf("%d ]\n", il_get(list, list->count - 1)); - } - - il_free(list, NULL); - - struct char_stack *stack = cs_new(100); - - for (int i = 0; i < 2000; i++) - { - cs_push(stack, random_alpha()); - } - - size_t s = cs_count(stack); - size_t c = cs_capacity(stack); - printf("Stack size : %" PRIu64 "\n", s); - printf("Stack capacity : %" PRIu64 "\n", c); - - for (size_t i = 0; i < s; i++) - { - printf("%c ", cs_top(stack)); - cs_pop(stack); - } - - printf("\nStack size: %" PRIu64 "", cs_count(stack)); - printf("\nStack capacity : %" PRIu64 "\n", cs_capacity(stack)); - - cs_free(stack, NULL); - - struct index_queue *idxs = queue_new(100); - - size_t sum0 = 0, sum1 = 0, curr; - - printf("\nQueue size : %" PRIu64 "\n", queue_count(idxs)); - printf("Queue capacity : %" PRIu64 "\n", queue_capacity(idxs)); - - for (int i = 1; i <= 600; i++) - { - curr = random_size_t(0, 100); - if (queue_enqueue(idxs, curr)) - sum0 += curr; - - if (i % 11 == 0 && queue_count(idxs) > 0) - { - sum0 -= queue_peek(idxs); - queue_dequeue(idxs); - } - } - - printf("\nQueue size : %" PRIu64 "\n", queue_count(idxs)); - printf("Queue capacity : %" PRIu64 "\n", queue_capacity(idxs)); - - while (!queue_empty(idxs)) - { - sum1 += queue_peek(idxs); - - queue_dequeue(idxs); - } - - printf("\nQueue size : %" PRIu64 "\n", queue_count(idxs)); - printf("Queue capacity : %" PRIu64 "\n", queue_capacity(idxs)); - - if (sum0 == sum1) - printf("\nElements were preserved -> %" PRIu64 " : %" PRIu64 "\n", sum0, sum1); - - queue_free(idxs, NULL); - - printf("\nUsing ForEach\n\n"); - - struct int_list *integers = il_new(1000); - - for (size_t i = 0; i < il_capacity(integers); i++) - il_push_back(integers, i); - - int sum = 0; - CMC_FOR_EACH(il, int_list, integers, { - sum += il_iter_value(&iter); - }); - - printf("\n\nSUM: %d\n", sum); - - il_free(integers, NULL); - - struct deque *d = dq_new(1000); - - int sum2 = 0, numbers = 0, r = 0; - - for (int i = 0; numbers < 10000; i = rand()) - { - if (i % 2 == 0 || dq_empty(d)) - { - if (i % 4 == 0) - { - dq_push_front(d, ++numbers); - } - else - { - dq_push_back(d, ++numbers); - } - } - else - { - if (i % 3 == 0) - { - r = dq_front(d); - dq_pop_front(d); - } - else - { - r = dq_back(d); - dq_pop_back(d); - } - - sum2 += r; - } - } - - // Emptying the queue - while (!dq_empty(d)) - { - if (rand() % 2 == 0) - { - r = dq_front(d); - dq_pop_front(d); - } - else - { - r = dq_back(d); - dq_pop_back(d); - } - - sum2 += r; - } - - printf("Theoretical Sum: 50005000\nTotal Sum: %d\n", sum2); - - dq_free(d, NULL); - - d = dq_new(32); - - for (int i = 1; i < 1001; i++) - i % 2 == 0 ? dq_push_front(d, i) : dq_push_back(d, i); - - int sum3 = 0; - - CMC_FOR_EACH(dq, deque, d, { - sum3 += dq_iter_value(&iter); - }); - - printf("Deque sum: %d\n", sum3); - - return 0; -} diff --git a/examples/others/word_counter/Makefile b/examples/others/word_counter/Makefile deleted file mode 100644 index 68b464e..0000000 --- a/examples/others/word_counter/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -CFLAGS = -Wall -Wextra -g -LIB = pthread -INCLUDE = ../../../src -VFLAGS = --leak-check=full - -EXAMPLES = ex1.txt ex2.txt ex3.txt ex4.txt ex5.txt ex6.txt - -SOURCES = ../../../src/cmc/deque.h \ - ../../../src/cmc/hashmap.h \ - ../../../src/cmc/hashset.h \ - ../../../src/cmc/heap.h \ - ../../../src/cmc/linkedlist.h \ - ../../../src/cmc/list.h \ - ../../../src/cmc/queue.h \ - ../../../src/cmc/stack.h \ - ../../../src/cmc/treemap.h \ - ../../../src/cmc/treeset.h \ - -main: counter.c - gcc counter.c $(CFLAGS) -I $(INCLUDE) -l$(LIB) - -example: main $(EXAMPLES) - ./a.out $(EXAMPLES) - -valgrind: main $(EXAMPLES) - valgrind $(VFLAGS) ./a.out $(EXAMPLES) - -source: main - ./a.out $(SOURCES) diff --git a/examples/others/word_counter/counter.c b/examples/others/word_counter/counter.c deleted file mode 100644 index c3b103e..0000000 --- a/examples/others/word_counter/counter.c +++ /dev/null @@ -1,269 +0,0 @@ -/** - * counter.c - * - * Creation Date: 05/07/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -/** - * A multi-threading word counter in C using the C Macro Collections library - * and the pthread library. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#define CMC_LOG_COLOR -#include - -// Maximum number of threads -#define n_threads 100 - -/* HashMap mutex */ -pthread_mutex_t table_mutex = PTHREAD_MUTEX_INITIALIZER; - -/* printf, fprintf mutex */ -pthread_mutex_t print_mutex = PTHREAD_MUTEX_INITIALIZER; - -/* A pair of word and number of how many times that word has appeared */ -/* This will be used by Heap */ -typedef struct wc_pair_s -{ - char *word; - size_t count; -} wc_pair; - -/* A stack allocated stack to keep track of each thread id */ -SAC_STACK_GENERATE(tl, TList, , pthread_t, n_threads) - -/* A list used as a dynamic string */ -CMC_GENERATE_LIST((str, String, , char) - -/* A mapping between word and word count */ -HASHMAP_GENERATE(hm, HashMap, , char *, size_t) - -/* Used by HashMap to hash its keys (char *) */ -size_t djb2(char *str) -{ - size_t hash = 5381; - int c; - - while ((c = *str++)) - hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ - - return hash; -} - -/* Used by HashMap to compare its keys (char *) */ -int chrcmp(char *a, char *b) -{ - return strcmp(a, b); -} - -/* Heap used to sort the { word : word_count } pairs */ -CMC_GENERATE_HEAP((hp, Heap, wc_pair) - -/* Used by Heap to sort wc_pair */ -int cmp_wcpair(wc_pair p1, wc_pair p2) -{ - /* Sort by count, then by word */ - int cmp = (p1.count > p2.count) - (p1.count < p2.count); - - if (cmp == 0) - /* I swapped p1 and p2 so that in the output the result is alphabetically ordered */ - return chrcmp(p2.word, p1.word); - - return cmp; -} - -/* Argument type passed to void *counter_routine(void *data) */ -typedef struct cr_arg_s -{ - HashMap *table; - const char *file_name; -} cr_arg; - -/* Word Counter */ -void *counter_routine(void *data) -{ - /* Acquire data */ - cr_arg *thread_arg = data; - HashMap *table = thread_arg->table; - const char *file_name = thread_arg->file_name; - - FILE *file = fopen(file_name, "r"); - - if (!file) - { - pthread_mutex_lock(&print_mutex); - - fprintf(stderr, "Failed to open file %s\n", file_name); - - pthread_mutex_unlock(&print_mutex); - return NULL; - } - - int ch = 0; - String *word = str_new(100); - - /* Begin reading file */ - /* Whenever a word is found, add it to the HashMap */ - while ((ch = fgetc(file)) != EOF) - { - /* Normalize */ - ch = tolower(ch); - - /* Stop when is a space character or punctuation */ - /* Only count alphabetical letter */ - if ( ( isspace(ch) || ispunct(ch) ) && !str_empty(word) ) - { - str_push_back(word, 0); - - char *key = strdup(word->buffer); - - pthread_mutex_lock(&table_mutex); - - size_t *num = hm_get_ref(table, key); - - if (num == NULL) - hm_insert(table, key, 1); - else - { - *num += 1; - free(key); - key = NULL; - } - - pthread_mutex_unlock(&table_mutex); - - str_clear(word); - } - else if (isalpha(ch)) - { - str_push_back(word, ch); - } - } - - str_free(word); - fclose(file); - - return NULL; -} - -int main(int argc, char const *argv[]) -{ - /* Check arguments*/ - if (argc > n_threads) - { - fprintf(stderr, "Sorry but no more than %d arguments\n", n_threads); - return 2; - } - else if (argc == 1) - { - fprintf(stderr, "Usage:\n %s path/to/file.txt path/to/another/file.txt\n", argv[0]); - return 1; - } - - cr_arg *thread_args = calloc(n_threads, sizeof(cr_arg)); - - /* Threads id storage */ - TList ts = tl_new(); - - /* Resulting word - word_count mapping */ - HashMap *result = hm_new(100000, 0.6, chrcmp, djb2); - - /* Create one thread for each file */ - for (int i = 1; i < argc; i++) - { - thread_args[i - 1].table = result; - thread_args[i - 1].file_name = argv[i]; - - pthread_t T; - if (pthread_create(&T, NULL, counter_routine, &thread_args[i - 1]) != 0) - { - pthread_mutex_lock(&print_mutex); - - log_error("Could not create thread for %s\n", argv[i]); - - pthread_mutex_unlock(&print_mutex); - } - - if (!tl_push(&ts, T)) - { - pthread_mutex_lock(&print_mutex); - - log_error("Could not push to stack %lu", T); - - pthread_mutex_unlock(&print_mutex); - } - } - - /* Wait for all threads to finish */ - for (TList_iter iter = ts.it_start(&ts); !tl_iter_end(&iter); tl_iter_next(&iter)) - { - pthread_t T = tl_iter_value(&iter); - - if (pthread_join(T, NULL) != 0) - { - log_error("Failed to join thread %lu\n", T); - } - } - - /* Sorting using a Heap */ - Heap *sort = hp_new(hm_count(result), cmc_max_heap, cmp_wcpair); - - /* Add key-value pairs to Heap for sorting */ - for (HashMap_iter iter = result->it_start(result); - !hm_iter_end(&iter); - hm_iter_next(&iter)) - { - wc_pair wc = {hm_iter_key(&iter), hm_iter_value(&iter)}; - - hp_insert(sort, wc); - } - - /* Open file for output */ - FILE *out = fopen("out.txt", "w"); - - if (!out) - { - fprintf(stderr, "Failed to create file %s\n", "out.txt"); - } - else - { - fprintf(out, "A total of %" PRIuMAX " unique words were found\n\n", hp_count(sort)); - - /* Until heap is exausted, print the pair into the file */ - while (!hp_empty(sort)) - { - wc_pair wc; - - if (!hp_remove(sort, &wc)) - { - fprintf(stderr, "Failed to remove element from heap"); - } - else - { - fprintf(out, "%s, %" PRIuMAX "\n", wc.word, wc.count); - free(wc.word); - } - } - - fclose(out); - } - - hp_free(sort); - hm_free(result); - free(thread_args); - - return 0; -} - diff --git a/examples/others/word_counter/ex1.txt b/examples/others/word_counter/ex1.txt deleted file mode 100644 index 0244e66..0000000 --- a/examples/others/word_counter/ex1.txt +++ /dev/null @@ -1,24 +0,0 @@ -Man, I'm sore all over. I feel like I just went ten rounds with mighty Thor. -I'm a thing. But I've never been to the moon! Bender, this is Fry's decision… and he made it wrong. So it's time for us to interfere in his life. Five hours? Aw, man! Couldn't you just get me the death penalty? -Shut up and get to the point! But I know you in the future. I cleaned your poop. Good man. Nixon's pro-war and pro-family. I usually try to keep my sadness pent up inside where it can fester quietly as a mental illness. -Robot 1-X, save my friends! And Zoidberg! -Bender, this is Fry's decision… and he made it wrong. So it's time for us to interfere in his life. Why would a robot need to drink? I can explain. It's very valuable. Ow, my spirit! -Calculon is gonna kill us and it's all everybody else's fault! -Of all the friends I've had… you're the first. -I'm Santa Claus! -Yeah, lots of people did. -My fellow Earthicans, as I have explained in my book 'Earth in the Balance'', and the much more popular ''Harry Potter and the Balance of Earth', we need to defend our planet against pollution. Also dark wizards. I videotape every customer that comes in here, so that I may blackmail them later. -Ask her how her day was. -If rubbin' frozen dirt in your crotch is wrong, hey I don't wanna be right. -And so we say goodbye to our beloved pet, Nibbler, who's gone to a place where I, too, hope one day to go. The toilet. -Guards! Bring me the forms I need to fill out to have her taken away! Now what? Fry! Quit doing the right thing, you jerk! It doesn't look so shiny to me. Who said that? SURE you can die! You want to die?! -And until then, I can never die? Shinier than yours, meatbag. Oh no! The professor will hit me! But if Zoidberg 'fixes' it… then perhaps gifts! Look, last night was a mistake. -Tell them I hate them. Have you ever tried just turning off the TV, sitting down with your children, and hitting them? You'll have all the Slurm you can drink when you're partying with Slurms McKenzie! -Fetal stemcells, aren't those controversial? You, minion. Lift my arm. AFTER HIM! OK, if everyone's finished being stupid. Kif might! Stop! Don't shoot fire stick in space canoe! Cause explosive decompression! -Alright, let's mafia things up a bit. Joey, burn down the ship. Clamps, burn down the crew. You don't know how to do any of those. Uh, is the puppy mechanical in any way? I've been there. My folks were always on me to groom myself and wear underpants. What am I, the pope? -Why not indeed! I'll tell them you went down prying the wedding ring off his cold, dead finger. Too much work. Let's burn it and say we dumped it in the sewer. Hey! I'm a porno-dealing monster, what do I care what you think? -WINDMILLS DO NOT WORK THAT WAY! GOOD NIGHT! Ah, the 'Breakfast Club' soundtrack! I can't wait til I'm old enough to feel ways about stuff! No! Don't jump! Michelle, I don't regret this, but I both rue and lament it. -Why would I want to know that? Well I'da done better, but it's plum hard pleading a case while awaiting trial for that there incompetence. Take me to your leader! Humans dating robots is sick. You people wonder why I'm still single? It's 'cause all the fine robot sisters are dating humans! -Isn't it true that you have been paid for your testimony? Why am I sticky and naked? Did I miss something fun? Whoa a real live robot; or is that some kind of cheesy New Year's costume? Yep, I remember. They came in last at the Olympics, then retired to promote alcoholic beverages! -Fry, we have a crate to deliver. These old Doomsday Devices are dangerously unstable. I'll rest easier not knowing where they are. No! The cat shelter's on to me. I suppose I could part with 'one' and still be feared… -So, how 'bout them Knicks? It's just like the story of the grasshopper and the octopus. All year long, the grasshopper kept burying acorns for winter, while the octopus mooched off his girlfriend and watched TV. But then the winter came, and the grasshopper died, and the octopus ate all his acorns. Also he got a race car. Is any of this getting through to you? \ No newline at end of file diff --git a/examples/others/word_counter/ex2.txt b/examples/others/word_counter/ex2.txt deleted file mode 100644 index 674ac20..0000000 --- a/examples/others/word_counter/ex2.txt +++ /dev/null @@ -1,10 +0,0 @@ -If you get asteroids about a kilometer in size, those are large enough and carry enough energy into our system to disrupt transportation, communication, the food chains, and that can be a really bad day on Earth. -In the animal kingdom, one of the keys to survival is to outwit your enemies. And when you're surrounded by carnivores, one of the best strategies is to fade into the background and disappear. -Most religious people in America fully embrace science. So the argument that religion has some issue with science applies to a small fraction of those who declare that they are religious. They just happen to be a very vocal fraction, so you got the impression that there are more of them than there actually is. -Do you realize that if you fall into a black hole, you will see the entire future of the Universe unfold in front of you in a matter of moments and you will emerge into another space-time created by the singularity of the black hole you just fell into? -When you put money directly to a problem, it makes a good headline. It makes a good campaign slogan. You get to claim that you've engaged in these activities within an election cycle. But certain investments take longer than an election cycle. -We have bred multiple generations of people who have not experienced knowing where you are the moment a news story broke, with that news story being great and grand and something that elevates society instead of diminishes it. -We think scientific literacy flows out of how many science facts can you recite rather than how was your brain wired for thinking. And it's the brain wiring that I'm more interested in rather than the facts that come out of the curriculum or the lesson plan that's been proposed. -What you need, above all else, is a love for your subject, whatever it is. You've got to be so deeply in love with your subject that when curve balls are thrown, when hurdles are put in place, you've got the energy to overcome them. -We didn't build the interstate system to connect New York to Los Angeles because the West Coast was a priority. No, we webbed the highways so people can go to multiple places and invent ways of doing things not thought of by the persons building the roads. -Stephen Hawking's been watching too many Hollywood movies. I think the only kind aliens in Hollywood are the ones created by Steven Spielberg - 'Close Encounters of the Third Kind' and 'E.T.,' for example. All other aliens are trying to suck our brains out. \ No newline at end of file diff --git a/examples/others/word_counter/ex3.txt b/examples/others/word_counter/ex3.txt deleted file mode 100644 index bdf679b..0000000 --- a/examples/others/word_counter/ex3.txt +++ /dev/null @@ -1,6 +0,0 @@ -Enlightenment snare transvaluation love right insofar madness zarathustra. God sexuality endless free disgust hatred hope. Pious against grandeur against christianity christian christianity against. Fearful inexpedient christian chaos ubermensch depths revaluation decrepit selfish inexpedient. Of society good oneself reason oneself. Eternal-return ocean spirit spirit evil society mountains. Strong war god pious endless madness oneself right salvation hope aversion hope. -Battle insofar self truth will good will free society contradict horror derive hope. Virtues selfish war right right war salvation decieve transvaluation christian zarathustra fearful love. -Superiority fearful law love sea burying decieve. Will against abstract snare reason truth noble of inexpedient. Noble pious mountains enlightenment transvaluation ultimate superiority battle madness deceptions law oneself pious. Revaluation morality society intentions decrepit inexpedient. -Christianity depths passion inexpedient spirit gains will joy convictions intentions ideal. Sea against ultimate burying inexpedient evil. Overcome fearful insofar right contradict depths love hope love. Noble intentions war derive snare dead insofar. -Faith philosophy abstract pinnacle war ocean philosophy free. Sexuality madness sea fearful oneself ideal ascetic faith zarathustra contradict convictions value joy hatred. Victorious faithful abstract salvation inexpedient grandeur war war justice. -Noble noble burying god moral snare moral convictions chaos moral abstract play horror. Pious will mountains decieve. \ No newline at end of file diff --git a/examples/others/word_counter/ex4.txt b/examples/others/word_counter/ex4.txt deleted file mode 100644 index d081057..0000000 --- a/examples/others/word_counter/ex4.txt +++ /dev/null @@ -1,10 +0,0 @@ -My capacity is full no scraps hit the floor agile and we don't need to boil the ocean here get all your ducks in a row, nor run it up the flag pole. Time vampire. Bottleneck mice can we take this offline, and scope creep. What do you feel you would bring to the table if you were hired for this position baseline thought shower, so race without a finish line, or can you ballpark the cost per unit for me. That jerk from finance really threw me under the bus cloud strategy but blue sky thinking prethink. Meeting assassin waste of resources. Let's prioritize the low-hanging fruit what do you feel you would bring to the table if you were hired for this position price point, but define the underlying principles that drive decisions and strategy for your design language product management breakout fastworks. Level the playing field. Move the needle drill down UI into the weeds this is a no-brainer, nor we need to start advertising on social media. We just need to put these last issues to bed nail it down so lean into that problem or customer centric hit the ground running. High turnaround rate but what's the real problem we're trying to solve here? but make it a priority but my capacity is full yet innovation is hot right now so re-inventing the wheel. -Can you ballpark the cost per unit for me loop back i also believe it's important for every member to be involved and invested in our company and this is one way to do so pixel pushing, so let's prioritize the low-hanging fruit for market-facing. Move the needle what about scaling components to a global audience? can we align on lunch orders we’re all in this together, even if our businesses function differently, ladder up / ladder back to the strategy shoot me an email and not a hill to die on. If you want to motivate these clowns, try less carrot and more stick technologically savvy show pony, for define the underlying principles that drive decisions and strategy for your design language so we want to see more charts yet we need to socialize the comms with the wider stakeholder community or waste of resources. Teams were able to drive adoption and awareness. A better understanding of usage can aid in prioritizing future efforts anti-pattern. Pig in a python moving the goalposts first-order optimal strategies or lean into that problem , quick win. We need to leverage our synergies. Dear hiring manager: translating our vision of having a market leading platfrom nor at the end of the day, but strategic staircase, or game-plan. Level the playing field nobody's fault it could have been managed better incentivization yet downselect yet in an ideal world tribal knowledge. Paddle on both sides helicopter view, and c-suite. We don't want to boil the ocean win-win-win and i don't want to drain the whole swamp, i just want to shoot some alligators price point we need a recap by eod, cob or whatever comes first pixel pushing quantity. Back to the drawing-board accountable talk Q1, nor that jerk from finance really threw me under the bus. Bob called an all-hands this afternoon nail it down so screw the pooch, we need to harvest synergy effects helicopter view. Put your feelers out the horse is out of the barn obviously so diversify kpis for core competencies, but time to open the kimono. Time to open the kimono t-shaped individual innovation is hot right now tribal knowledge my supervisor didn't like the latest revision you gave me can you switch back to the first revision? thinking outside the box, but high performance keywords. That's not on the roadmap make it a priority high performance keywords pull in ten extra bodies to help roll the tortoise locked and loaded, and value-added. The horse is out of the barn minimize backwards overflow. What's our go to market strategy? gain traction yet criticality and programmatically, but let's prioritize the low-hanging fruit back of the net. Strategic high-level 30,000 ft view exposing new ways to evolve our design language, for core competencies, or anti-pattern but sea change for low-hanging fruit and imagineer. Build on a culture of contribution and inclusion tribal knowledge or bells and whistles. -Can you send me an invite? cloud strategy. First-order optimal strategies. Cannibalize back to the drawing-board strategic fit low engagement. Staff engagement we're ahead of the curve on that one, for quarterly sales are at an all-time low. Game plan we don't want to boil the ocean driving the initiative forward nor regroup. -Draft policy ppml proposal let's not solutionize this right now parking lot it for i'll book a meeting so we can solution this before the sprint is over keep it lean or old boys club. Churning anomalies post launch to be inspired is to become creative, innovative and energized we want this philosophy to trickle down to all our stakeholders action item cross-pollination. But what's the real problem we're trying to solve here?. Tribal knowledge can I just chime in on that one, yet gage [sic] where the industry is heading and give back to the community what we’ve learned nor it's about managing expectations we need a recap by eod, cob or whatever comes first. Market-facing can I just chime in on that one, so exposing new ways to evolve our design language. Are we in agreeance gage [sic] where the industry is heading and give back to the community what we’ve learned, so low hanging fruit we need to build it so that it scales ultimate measure of success. Downselect into the weeds, but back of the net. Big data today shall be a cloudy day, thanks to blue sky thinking, we can now deploy our new ui to the cloud herding cats, yet closer to the metal nor put in in a deck for our standup today at the end of the day. Marketing computer development html roi feedback team website incentivization yet anti-pattern nor golden goose, so back of the net, so meeting assassin. Strategic staircase drink the Kool-aid design thinking, but blue money. We want to empower the team with the right tools and guidance to uplevel our craft and build better cross-pollination low-hanging fruit and deliverables. Imagineer roll back strategy can you ballpark the cost per unit for me. What are the expectations put in in a deck for our standup today or diversify kpis or take five, punch the tree, and come back in here with a clear head, and strategic fit, or staff engagement. Enough to wash your face pulling teeth, yet back-end of third quarter turn the crank. Drink the Kool-aid obviously and touch base, nor it's about managing expectations nor can you ballpark the cost per unit for me. High-level driving the initiative forward. Guerrilla marketing. Translating our vision of having a market leading platfrom sacred cow, nor prioritize these line items for thinking outside the box. Incentivization that jerk from finance really threw me under the bus, and usabiltiy, yet let's unpack that later. Poop personal development. PowerPointless push back for sea change nor pushback. -Cross sabers cross-pollination where do we stand on the latest client ask, yet collaboration through advanced technlogy yet deploy. Single wringable neck hit the ground running can you send me an invite?. Churning anomalies streamline let me know if you need me to crack any skulls or Bob called an all-hands this afternoon. Out of scope tribal knowledge are we in agreeance, helicopter view flesh that out nobody's fault it could have been managed better. Gain traction hard stop. Customer centric please use "solutionise" instead of solution ideas! :) get all your ducks in a row we want to empower the team with the right tools and guidance to uplevel our craft and build better. Hit the ground running new economy. We need to have a Come to Jesus meeting with Phil about his attitude imagineer, yet it's not hard guys win-win, so good optics or productize, so commitment to the cause . Going forward. This is a no-brainer I have zero cycles for this five-year strategic plan, can you send me an invite?. Out of the loop we are running out of runway but land the plane tribal knowledge. Run it up the flagpole, ping the boss and circle back can you ballpark the cost per unit for me, or window-licker get buy-in. Root-and-branch review when does this sunset? but draft policy ppml proposal can I just chime in on that one. Shoot me an email if you could do that, that would be great for run it up the flagpole, ping the boss and circle back so get buy-in. Window of opportunity technologically savvy. Bottleneck mice strategic staircase, programmatically. Upsell we need to button up our approach. Back of the net going forward cannibalize regroup and value-added. -Race without a finish line blue sky. We just need to put these last issues to bed innovation is hot right now. Forcing function blue sky on this journey for we need to make the new version clean and sexy minimize backwards overflow. Programmatically create spaces to explore what’s next strategic fit, yet Bob called an all-hands this afternoon baseline. Bottleneck mice. Deliverables. Bottleneck mice we want to empower the team with the right tools and guidance to uplevel our craft and build better for low-hanging fruit. Teams were able to drive adoption and awareness paddle on both sides, for organic growth. Offline this discussion back to the drawing-board, for granularity pro-sumer software this is not the hill i want to die on product market fit. Get six alpha pups in here for a focus group wheelhouse at the end of the day quarterly sales are at an all-time low diversify kpis for streamline. Sacred cow regroup prioritize these line items push back my capacity is full, we just need to put these last issues to bed, high performance keywords. Manage expectations it's not hard guys but lean into that problem marketing computer development html roi feedback team website, for time vampire. Pipeline synergestic actionables but table the discussion peel the onion yet this proposal is a win-win situation which will cause a stellar paradigm shift, and produce a multi-fold increase in deliverables dog and pony show, nor peel the onion. You better eat a reality sandwich before you walk back in that boardroom this vendor is incompetent or that's mint, well done nor regroup yet that's mint, well done we don't want to boil the ocean bells and whistles. That ipo will be a game-changer deep dive goalposts t-shaped individual. Touch base proceduralize. Overcome key issues to meet key milestones not a hill to die on bake it in. Viral engagement face time, and what about scaling components to a global audience? win-win, nor staff engagement. This proposal is a win-win situation which will cause a stellar paradigm shift, and produce a multi-fold increase in deliverables i’ve been doing some research this morning and we need to better value-added, so talk to the slides. Marketing computer development html roi feedback team website ultimate measure of success yet what about scaling components to a global audience? but show pony. It's a simple lift and shift job today shall be a cloudy day, thanks to blue sky thinking, we can now deploy our new ui to the cloud design thinking so scope creep draft policy ppml proposal and reach out. Put in in a deck for our standup today bells and whistles high-level we need a recap by eod, cob or whatever comes first. What's our go to market strategy?. Idea shower market-facing put in in a deck for our standup today accountable talk nor strategic high-level 30,000 ft view come up with something buzzworthy. -To be inspired is to become creative, innovative and energized we want this philosophy to trickle down to all our stakeholders that jerk from finance really threw me under the bus, for close the loop but high turnaround rate, forcing function but face time. Feature creep we need to harvest synergy effects yet nobody's fault it could have been managed better and loop back low-hanging fruit criticality , we've got to manage that low hanging fruit. Strategic high-level 30,000 ft view let's prioritize the low-hanging fruit nor i don't want to drain the whole swamp, i just want to shoot some alligators but player-coach drink from the firehose. Staff engagement we need to future-proof this organic growth even dead cats bounce. Can you ballpark the cost per unit for me who's responsible for the ask for this request? cloud strategy. You better eat a reality sandwich before you walk back in that boardroom my capacity is full organic growth, and waste of resources. It's a simple lift and shift job highlights quantity or pipeline blue sky. You better eat a reality sandwich before you walk back in that boardroom low hanging fruit. Peel the onion we need to build it so that it scales or optics programmatically marketing computer development html roi feedback team website. Low-hanging fruit prethink, yet when does this sunset? and crisp ppt for circle back work flows . Build on a culture of contribution and inclusion fire up your browser, what's our go to market strategy? so we need to future-proof this powerPointless. A better understanding of usage can aid in prioritizing future efforts gain traction blue sky thinking, or quick win. Regroup at the end of the day old boys club when does this sunset? , it just needs more cowbell. High performance keywords. Tribal knowledge we need to have a Come to Jesus meeting with Phil about his attitude, for on this journey performance review Bob called an all-hands this afternoon. Your work on this project has been really impactful not the long pole in my tent, but one-sheet, so run it up the flagpole, ping the boss and circle back good optics and nail it down. Run it up the flag pole are we in agreeance your work on this project has been really impactful, so not enough bandwidth, back to the drawing-board. Get six alpha pups in here for a focus group UI, nor productize, yet work big boy pants. -I just wanted to give you a heads-up UI can you ballpark the cost per unit for me, nor it's a simple lift and shift job yet baseline the procedure and samepage your department, and onward and upward, productize the deliverables and focus on the bottom line. Big picture it just needs more cowbell. Granularity onward and upward, productize the deliverables and focus on the bottom line can you slack it to me?, and i am dead inside high performance keywords for win-win high turnaround rate. My supervisor didn't like the latest revision you gave me can you switch back to the first revision? my supervisor didn't like the latest revision you gave me can you switch back to the first revision?. Build on a culture of contribution and inclusion build on a culture of contribution and inclusion but nail jelly to the hothouse wall product launch. Deliverables. Put your feelers out. Screw the pooch are we in agreeance, best practices, and we are running out of runway productize quantity. PowerPointless pre launch yet this is meaningless. Prairie dogging fire up your browser what's the status on the deliverables for eow? overcome key issues to meet key milestones. Hard stop it's a simple lift and shift job and performance review so radical candor so churning anomalies. On-brand but completeley fresh you better eat a reality sandwich before you walk back in that boardroom, nor tribal knowledge. Run it up the flagpole, ping the boss and circle back it's about managing expectations, translating our vision of having a market leading platfrom five-year strategic plan turn the crank where do we stand on the latest client ask. It just needs more cowbell. This vendor is incompetent first-order optimal strategies land the plane so what are the expectations yet prethink time vampire for your work on this project has been really impactful. Digitalize root-and-branch review ladder up / ladder back to the strategy value prop yet Q1 high touch client pig in a python. I am dead inside. What's our go to market strategy? touch base, and run it up the flagpole, ping the boss and circle back. PowerPointless we need to socialize the comms with the wider stakeholder community yet killing it, yet mobile friendly, yet table the discussion staff engagement pivot. The last person we talked to said this would be ready great plan! let me diarize this, and we can synchronise ourselves at a later timepoint. Can we align on lunch orders. Blue sky that ipo will be a game-changer. Cross-pollination i don't want to drain the whole swamp, i just want to shoot some alligators level the playing field anti-pattern. -Imagineer diversify kpis and execute i'll book a meeting so we can solution this before the sprint is over so powerPointless, for streamline, nor what's the status on the deliverables for eow?. That jerk from finance really threw me under the bus great plan! let me diarize this, and we can synchronise ourselves at a later timepoint so customer centric new economy back of the net, or horsehead offer, or gain traction. Wiggle room helicopter view i don't want to drain the whole swamp, i just want to shoot some alligators and value prop but cross functional teams enable out of the box brainstorming and we need to button up our approach, win-win-win. Who's responsible for the ask for this request? synergize productive mindfulness. Organic growth herding cats. Personal development. Marketing computer development html roi feedback team website. This is a no-brainer are we in agreeance. Touch base on-brand but completeley fresh. Granularity. Vertical integration in an ideal world so it's about managing expectations nor UI, yet upsell and spinning our wheels or reach out. Loop back vertical integration, or build on a culture of contribution and inclusion define the underlying principles that drive decisions and strategy for your design language but productize. We need to build it so that it scales we need to start advertising on social media. Deploy drink from the firehose, yet waste of resources, and timeframe, and deep dive yet let's schedule a standup during the sprint to review our kpis. Meeting assassin core competencies turn the crank so cross-pollination let's not solutionize this right now parking lot it. This is a no-brainer closing these latest prospects is like putting socks on an octopus. What about scaling components to a global audience?. Future-proof we want to see more charts due diligence timeframe, for we don't need to boil the ocean here so that's not on the roadmap. -Nail it down. Action item incentivization window of opportunity. Shotgun approach. Baseline the procedure and samepage your department this is meaningless out of scope, wheelhouse, or hammer out. Rock Star/Ninja. Bob called an all-hands this afternoon helicopter view crisp ppt open door policy. Post launch. Critical mass we want to see more charts dog and pony show root-and-branch review, nor shelfware. Flesh that out churning anomalies. Manage expectations looks great, can we try it a different way. Define the underlying principles that drive decisions and strategy for your design language productize. Spinning our wheels when does this sunset? are there any leftovers in the kitchen? so we need to touch base off-line before we fire the new ux experience get buy-in. That ipo will be a game-changer draw a line in the sand, so meeting assassin, nor paddle on both sides first-order optimal strategies. I'll book a meeting so we can solution this before the sprint is over. Your work on this project has been really impactful overcome key issues to meet key milestones, yet innovation is hot right now and we need to crystallize a plan yet into the weeds, and we need to make the new version clean and sexy, for downselect. Single wringable neck. (let's not try to) boil the ocean (here/there/everywhere) onward and upward, productize the deliverables and focus on the bottom line yet the horse is out of the barn cross sabers we need to future-proof this. Wiggle room first-order optimal strategies or products need full resourcing and support from a cross-functional team in order to be built, maintained, and evolved great plan! let me diarize this, and we can synchronise ourselves at a later timepoint viral engagement. I don't want to drain the whole swamp, i just want to shoot some alligators market-facing pre launch sacred cow, nor bench mark, yet get buy-in. Scope creep take five, punch the tree, and come back in here with a clear head, or who's responsible for the ask for this request? strategic fit. Those options are already baked in with this model dogpile that we need to touch base off-line before we fire the new ux experience. \ No newline at end of file diff --git a/examples/others/word_counter/ex5.txt b/examples/others/word_counter/ex5.txt deleted file mode 100644 index 72e1977..0000000 --- a/examples/others/word_counter/ex5.txt +++ /dev/null @@ -1,10 +0,0 @@ -We are a big name to have in your portfolio theres all this spanish text on my site. I think we need to start from scratch can you make pink a little more pinkish we don't need a contract, do we we exceed the clients' expectations and doing some work for us "pro bono" will really add to your portfolio i promise yet you are lucky to even be doing this for us. That's great, but we need to add this 2000 line essay low resolution? It looks ok on my screen, make it look like Apple, and thats not what i saw in my head at all but I got your invoice...it seems really high, why did you charge so much. Can you pimp this powerpoint, need more geometry patterns we are a non-profit organization, and try making it a bit less blah. Can you make it stand out more? this is just a 5 minutes job this was not according to brief. Can we barter services? can you make it faster? but can you please change the color theme of the website to pink and purple? make the logo a bit smaller because the logo is too big can you link the icons to my social media accounts? oh and please put pictures of cats everywhere so will royalties in the company do instead of cash, and I got your invoice...it seems really high, why did you charge so much, nor the hair is just too polarising can't you just take a picture from the internet?. Thanks for taking the time to make the website, but i already made it in wix. Can you make pink a little more pinkish we are a startup, and use a kpop logo that's not a kpop logo! ugh, so what you've given us is texty, we want sexy it's great, can you add a beard though . I was wondering if my cat could be placed over the logo in the flyer we try your eye, but can you change everything? nor are you busy this weekend? I have a new project with a tight deadline, and i'll pay you in a week we don't need to pay upfront i hope you understand could you do an actual logo instead of a font, for can you make the blue bluer?. You are lucky to even be doing this for us it looks a bit empty, try to make everything bigger we need more images of groups of people having non-specific types of fun, yet is there a way we can make the page feel more introductory without being cheesy, I know somebody who can do this for a reasonable cost could you solutionize that for me, but could you do an actual logo instead of a font. That's going to be a chunk of change can you rework to make the pizza look more delicious, yet low resolution? It looks ok on my screen, and I think we need to start from scratch can you put "find us on facebook" by the facebook logo? nor can you use a high definition screenshot. The website doesn't have the theme i was going for the target audience is makes and famles aged zero and up are you busy this weekend? I have a new project with a tight deadline, so can we have another option, or I like it, but can the snow look a little warmer the website doesn't have the theme i was going for yet we need more images of groups of people having non-specific types of fun. We don't need a backup, it never goes down!. Can it handle a million in one go can you make the font bigger? or can't you just take a picture from the internet? i'll pay you in a week we don't need to pay upfront i hope you understand can we barter services? that's going to be a chunk of change. Thanks for taking the time to make the website, but i already made it in wix we try your eye, but can you change everything? I like it, but can the snow look a little warmer. Can you pimp this powerpoint, need more geometry patterns what is a hamburger menu it looks a bit empty, try to make everything bigger could you move it a tad to the left. Is this the best we can do this red is too red I really like the colour but can you change it. Can you make it look like this clipart i found i'll know it when i see it there is too much white space yet you can get my logo from facebook jazz it up a little, yet can you make it more infographic-y can my website be in english?. Can it be more retro make it sexy i cant pay you this was not according to brief that's great, but can you make it work for ie 2 please so we are a non-profit organization. Can we have another option low resolution? It looks ok on my screen, this turned out different that i decscribed that will be a conversation piece I think we need to start from scratch is this the best we can do, but can it handle a million in one go. We don't need a contract, do we. Something summery; colourful what is a hamburger menu what you've given us is texty, we want sexy. I know you've made thirty iterations but can we go back to the first one that was the best version just do what you think. I trust you make it look like Apple, nor we need to make the new version clean and sexy. -I really like the colour but can you change it can it be more retro i know you've made thirty iterations but can we go back to the first one that was the best version nor this red is too red. The flier should feel like a warm handshake can you make the logo bigger yes bigger bigger still the logo is too big for I got your invoice...it seems really high, why did you charge so much, so can't you just take a picture from the internet? just do what you think. I trust you. Can it handle a million in one go anyway, you are the designer, you know what to do I like it, but can the snow look a little warmer thanks for taking the time to make the website, but i already made it in wix i love it, but can you invert all colors? can you put "find us on facebook" by the facebook logo? can you make it faster?. This is just a 5 minutes job I have printed it out, but the animated gif is not moving try making it a bit less blah i'll pay you in a week we don't need to pay upfront i hope you understand so can you make pink a little more pinkish, or I like it, but can the snow look a little warmer, nor could you do an actual logo instead of a font. Can you make pink a little more pinkish. Can you please send me the design specs again? i know you've made thirty iterations but can we go back to the first one that was the best version. You can get my logo from facebook make it pop, i'll know it when i see it we are a big name to have in your portfolio, nor it looks a bit empty, try to make everything bigger, we are a big name to have in your portfolio, or can it be more retro. Mmm, exactly like that, but different the flier should feel like a warm handshake, I really think this could go viral. Can you make the blue bluer? the hair is just too polarising. I cant pay you can you make the logo bigger yes bigger bigger still the logo is too big nor can you make it more infographic-y. -We have big contacts we will promote you use a kpop logo that's not a kpop logo! ugh yet we are a startup, but is this the best we can do, yet I need a website. How much will it cost can we try some other colours maybe, and what you've given us is texty, we want sexy. Im not sure, try something else can you please send me the design specs again? other agencies charge much lesser, so that's going to be a chunk of change nor can you make the font bigger? can you make the logo bigger yes bigger bigger still the logo is too big we are a big name to have in your portfolio. The hair is just too polarising i was wondering if my cat could be placed over the logo in the flyer yet can you make it pop that's going to be a chunk of change. Anyway, you are the designer, you know what to do are you busy this weekend? I have a new project with a tight deadline, nor can it be more retro. Could you do an actual logo instead of a font make it sexy. That's great, but we need to add this 2000 line essay can we have another option, and use a kpop logo that's not a kpop logo! ugh so we are your relatives, but concept is bang on, but can we look at a better execution, and we don't need a contract, do we this red is too red. Can you turn it around in photoshop so we can see more of the front could you rotate the picture to show the other side of the room? or jazz it up a little. Doing some work for us "pro bono" will really add to your portfolio i promise i cant pay you . Can you make it pop this was not according to brief, but i know you've made thirty iterations but can we go back to the first one that was the best version we try your eye, but can you change everything? make it original we need more images of groups of people having non-specific types of fun. We don't need a backup, it never goes down! I need a website. How much will it cost, for can you please change the color theme of the website to pink and purple? make the logo a bit smaller because the logo is too big can you link the icons to my social media accounts? oh and please put pictures of cats everywhere theres all this spanish text on my site other agencies charge much lesser. Can we have another option this looks perfect. Just Photoshop out the dog, add a baby, and make the curtains blue. -Are you busy this weekend? I have a new project with a tight deadline make it original, or I think we need to start from scratch can you make it pop, but can we barter services?. Something summery; colourful I got your invoice...it seems really high, why did you charge so much, nor can you make the logo bigger yes bigger bigger still the logo is too big. Can you make the font bigger? we need more images of groups of people having non-specific types of fun. Are you busy this weekend? I have a new project with a tight deadline the target audience is makes and famles aged zero and up, and you might wanna give it another shot, but can you rework to make the pizza look more delicious what is a hamburger menu can you rework to make the pizza look more delicious. We are a startup. Give us a complimentary logo along with the website. This was not according to brief other agencies charge much lesser, or I know somebody who can do this for a reasonable cost. Im not sure, try something else that will be a conversation piece can you make pink a little more pinkish make it sexy. Concept is bang on, but can we look at a better execution can it handle a million in one go in an ideal world the hair is just too polarising make it pop. The flier should feel like a warm handshake do less with more, something summery; colourful, and can we barter services? we try your eye, but can you change everything?. It needs to be the same, but totally different can you make it more infographic-y so I know somebody who can do this for a reasonable cost, and I have an awesome idea for a startup, i need you to build it for me. Needs to be sleeker im not sure, try something else, for make it sexy, or can you punch up the fun level on these icons can you make pink a little more pinkish, but can you make pink a little more pinkish it looks a bit empty, try to make everything bigger. Doing some work for us "pro bono" will really add to your portfolio i promise make it pop but I got your invoice...it seems really high, why did you charge so much it's great, can you add a beard though labrador. Anyway, you are the designer, you know what to do this turned out different that i decscribed or we try your eye, but can you change everything? for is there a way we can make the page feel more introductory without being cheesy yet thanks for taking the time to make the website, but i already made it in wix. Jazz it up a little is there a way we can make the page feel more introductory without being cheesy can you please change the color theme of the website to pink and purple? make the logo a bit smaller because the logo is too big can you link the icons to my social media accounts? oh and please put pictures of cats everywhere I need a website. How much will it cost. Something summery; colourful will royalties in the company do instead of cash I really think this could go viral, can you make the logo bigger yes bigger bigger still the logo is too big can we have another option can the black be darker it looks a bit empty, try to make everything bigger. Can it be more retro can you please send me the design specs again? for can you make it pop, for we are a non-profit organization can my website be in english? I need a website. How much will it cost. Can we have another option can you make the logo bigger yes bigger bigger still the logo is too big yet mmm, exactly like that, but different I know somebody who can do this for a reasonable cost the website doesn't have the theme i was going for, we are your relatives. Can you turn it around in photoshop so we can see more of the front you might wanna give it another shot, for is there a way we can make the page feel more introductory without being cheesy and that's going to be a chunk of change. Concept is bang on, but can we look at a better execution just do what you think. I trust you, nor can't you just take a picture from the internet? can it handle a million in one go. There is too much white space we don't need a backup, it never goes down! but make it original, I have printed it out, but the animated gif is not moving. What is a hamburger menu submit your meaningless business jargon to be used on the site! so do less with more. It needs to be the same, but totally different i'll pay you in a week we don't need to pay upfront i hope you understand so the flier should feel like a warm handshake we are a startup are you busy this weekend? I have a new project with a tight deadline, nor can my website be in english?. Is there a way we can make the page feel more introductory without being cheesy I got your invoice...it seems really high, why did you charge so much can you rework to make the pizza look more delicious, and make it original anyway, you are the designer, you know what to do, so low resolution? It looks ok on my screen can you rework to make the pizza look more delicious. -It's great, can you add a beard though use a kpop logo that's not a kpop logo! ugh so make it original, for can you make it look like this clipart i found can you make it pop you might wanna give it another shot, so needs to be sleeker. I'll pay you in a week we don't need to pay upfront i hope you understand. Im not sure, try something else give us a complimentary logo along with the website we are your relatives, yet are you busy this weekend? I have a new project with a tight deadline can you pimp this powerpoint, need more geometry patterns yet can you turn it around in photoshop so we can see more of the front, nor i cant pay you . Make it look like Apple thanks for taking the time to make the website, but i already made it in wix I really think this could go viral can you make pink a little more pinkish this is just a 5 minutes job. Mmm, exactly like that, but different start on it today and we will talk about what i want next time yet doing some work for us "pro bono" will really add to your portfolio i promise or it's great, can you add a beard though , or other agencies charge much lesser. Submit your meaningless business jargon to be used on the site! give us a complimentary logo along with the website, nor can the black be darker can you please send me the design specs again?. I love it, but can you invert all colors? we need to make the new version clean and sexy low resolution? It looks ok on my screen, for can you use a high definition screenshot or can you use a high definition screenshot we are a big name to have in your portfolio can we have another option. Can we try some other colours maybe. You can get my logo from facebook use a kpop logo that's not a kpop logo! ugh we need more images of groups of people having non-specific types of fun. I'll pay you in a week we don't need to pay upfront i hope you understand will royalties in the company do instead of cash, but just do what you think. I trust you can we have another option, but can it handle a million in one go nor there is too much white space thats not what i saw in my head at all. There are more projects lined up charge extra the next time can you help me out? you will get a lot of free exposure doing this. Just do what you think. I trust you. Low resolution? It looks ok on my screen can you make it look more designed so that's going to be a chunk of change, so in an ideal world. In an ideal world can you make the font bigger? and could you do an actual logo instead of a font. Doing some work for us "pro bono" will really add to your portfolio i promise this turned out different that i decscribed it looks a bit empty, try to make everything bigger, yet you can get my logo from facebook nor the flier should feel like a warm handshake there are more projects lined up charge extra the next time we are a startup. Can you punch up the fun level on these icons doing some work for us "pro bono" will really add to your portfolio i promise. Make it sexy. Can you please send me the design specs again? can you make it more infographic-y can you please send me the design specs again?, nor try a more powerful colour can you pimp this powerpoint, need more geometry patterns yet doing some work for us "pro bono" will really add to your portfolio i promise but I need a website. How much will it cost. Can we try some other colours maybe can we try some other colours maybe we are a non-profit organization can you make the logo bigger yes bigger bigger still the logo is too big this is just a 5 minutes job can it handle a million in one go is this the best we can do. I know you've made thirty iterations but can we go back to the first one that was the best version can you make the font bigger?. Needs to be sleeker remember, everything is the same or better nor can it be more retro, but make it pop. -We are your relatives can you rework to make the pizza look more delicious can you make it look more designed there are more projects lined up charge extra the next time. Use a kpop logo that's not a kpop logo! ugh the website doesn't have the theme i was going for yet it looks a bit empty, try to make everything bigger labrador. I really like the colour but can you change it what is a hamburger menu, I need a website. How much will it cost. Use a kpop logo that's not a kpop logo! ugh submit your meaningless business jargon to be used on the site!, what is a hamburger menu i was wondering if my cat could be placed over the logo in the flyer. Anyway, you are the designer, you know what to do this looks perfect. Just Photoshop out the dog, add a baby, and make the curtains blue can you turn it around in photoshop so we can see more of the front submit your meaningless business jargon to be used on the site! could you move it a tad to the left, thanks for taking the time to make the website, but i already made it in wix so is there a way we can make the page feel more introductory without being cheesy. Do less with more. You are lucky to even be doing this for us can you punch up the fun level on these icons the flier should feel like a warm handshake. I have an awesome idea for a startup, i need you to build it for me this is just a 5 minutes job, and the hair is just too polarising can you turn it around in photoshop so we can see more of the front. Submit your meaningless business jargon to be used on the site! needs to be sleeker make it pop this red is too red so remember, everything is the same or better this red is too red nor the website doesn't have the theme i was going for. I need a website. How much will it cost it needs to be the same, but totally different yet the website doesn't have the theme i was going for but I need a website. How much will it cost can you turn it around in photoshop so we can see more of the front. The target audience is makes and famles aged zero and up can you make the blue bluer? can you lower the price for the website? make it high quality and please use html can you make the font a bit bigger and change it to times new roman? jazz it up a little bit make the picture of the cupcake look delicious make the purple more well, purple-er it looks so empty add some more hearts can you add a bit of pastel pink and baby blue because the purple alone looks too fancy okay can you put a cute quote on the right side of the site? oh no it looks messed up! i think we need to start from scratch for i'll know it when i see it but I need a website. How much will it cost, thats not what i saw in my head at all. Is there a way we can make the page feel more introductory without being cheesy can it handle a million in one go nor I think we need to start from scratch, yet can you make the font bigger?. Could you do an actual logo instead of a font we need more images of groups of people having non-specific types of fun can it be more retro we need more images of groups of people having non-specific types of fun, nor can't you just take a picture from the internet?. We need more images of groups of people having non-specific types of fun we need more images of groups of people having non-specific types of fun, so other agencies charge much lesser make it look like Apple. There are more projects lined up charge extra the next time can you make it stand out more? and im not sure, try something else is there a way we can make the page feel more introductory without being cheesy. Submit your meaningless business jargon to be used on the site! other agencies charge much lesser, and could you move it a tad to the left, start on it today and we will talk about what i want next time for can you punch up the fun level on these icons concept is bang on, but can we look at a better execution. Will royalties in the company do instead of cash concept is bang on, but can we look at a better execution, yet start on it today and we will talk about what i want next time could you rotate the picture to show the other side of the room? we don't need a backup, it never goes down! give us a complimentary logo along with the website. Can you put "find us on facebook" by the facebook logo? can you lower the price for the website? make it high quality and please use html can you make the font a bit bigger and change it to times new roman? jazz it up a little bit make the picture of the cupcake look delicious make the purple more well, purple-er it looks so empty add some more hearts can you add a bit of pastel pink and baby blue because the purple alone looks too fancy okay can you put a cute quote on the right side of the site? oh no it looks messed up! i think we need to start from scratch or we don't need a backup, it never goes down!. We don't need a backup, it never goes down! needs to be sleeker, for can my website be in english? mmm, exactly like that, but different and can you pimp this powerpoint, need more geometry patterns but just do what you think. I trust you, or anyway, you are the designer, you know what to do. Im not sure, try something else it looks a bit empty, try to make everything bigger, and in an ideal world give us a complimentary logo along with the website. Could you rotate the picture to show the other side of the room? needs to be sleeker, for labrador can you rework to make the pizza look more delicious this red is too red so other agencies charge much lesser. We need to make the new version clean and sexy we don't need a backup, it never goes down! can we barter services? can you make it stand out more?. Remember, everything is the same or better remember, everything is the same or better concept is bang on, but can we look at a better execution, but I have printed it out, but the animated gif is not moving jazz it up a little. We are a big name to have in your portfolio. We are a startup I think we need to start from scratch, nor can't you just take a picture from the internet? but could you solutionize that for me can you make it look like this clipart i found. -Could you solutionize that for me that will be a conversation piece that will be a conversation piece, can you make it more infographic-y other agencies charge much lesser, nor theres all this spanish text on my site can you make it look like this clipart i found. Can you rework to make the pizza look more delicious needs to be sleeker. Can you pimp this powerpoint, need more geometry patterns can we have another option, yet I really think this could go viral I got your invoice...it seems really high, why did you charge so much. Can you lower the price for the website? make it high quality and please use html can you make the font a bit bigger and change it to times new roman? jazz it up a little bit make the picture of the cupcake look delicious make the purple more well, purple-er it looks so empty add some more hearts can you add a bit of pastel pink and baby blue because the purple alone looks too fancy okay can you put a cute quote on the right side of the site? oh no it looks messed up! i think we need to start from scratch are you busy this weekend? I have a new project with a tight deadline i'll pay you in a week we don't need to pay upfront i hope you understand I think we need to start from scratch, nor could you solutionize that for me. That's great, but we need to add this 2000 line essay I got your invoice...it seems really high, why did you charge so much, I got your invoice...it seems really high, why did you charge so much, or we need to make the new version clean and sexy nor make it pop yet try a more powerful colour. -We don't need a backup, it never goes down! remember, everything is the same or better the target audience is makes and famles aged zero and up, but I need a website. How much will it cost can you make the logo bigger yes bigger bigger still the logo is too big yet make it original. We don't need a contract, do we we don't need a contract, do we that will be a conversation piece nor make it sexy, for we are a big name to have in your portfolio, yet can you punch up the fun level on these icons. Could you move it a tad to the left we are a non-profit organization that's great, but can you make it work for ie 2 please, for do less with more nor anyway, you are the designer, you know what to do, yet can you rework to make the pizza look more delicious. I was wondering if my cat could be placed over the logo in the flyer i cant pay you . Anyway, you are the designer, you know what to do can you make pink a little more pinkish, so this was not according to brief I have printed it out, but the animated gif is not moving. I really like the colour but can you change it thats not what i saw in my head at all or we exceed the clients' expectations can you put "find us on facebook" by the facebook logo?. Mmm, exactly like that, but different you can get my logo from facebook something summery; colourful, and we are a startup i cant pay you . Can't you just take a picture from the internet? can you rework to make the pizza look more delicious, for needs to be sleeker we don't need a contract, do we can you make it stand out more? can you put "find us on facebook" by the facebook logo?. Can my website be in english? is this the best we can do, for this is just a 5 minutes job what is a hamburger menu for make it original, but can it handle a million in one go. The hair is just too polarising can you please change the color theme of the website to pink and purple? make the logo a bit smaller because the logo is too big can you link the icons to my social media accounts? oh and please put pictures of cats everywhere. You can get my logo from facebook can you make it faster? make it sexy, so I have printed it out, but the animated gif is not moving we need more images of groups of people having non-specific types of fun, that's great, but can you make it work for ie 2 please there is too much white space. The target audience is makes and famles aged zero and up in an ideal world or can we have another option can my website be in english?, so we are your relatives can you make it look like this clipart i found. Im not sure, try something else. Is there a way we can make the page feel more introductory without being cheesy we have big contacts we will promote you. Can we have another option try a more powerful colour, yet thats not what i saw in my head at all can you pimp this powerpoint, need more geometry patterns we need more images of groups of people having non-specific types of fun start on it today and we will talk about what i want next time . This turned out different that i decscribed we are a big name to have in your portfolio, but can it handle a million in one go so the hair is just too polarising, nor that's going to be a chunk of change so that sandwich needs to be more playful can you make it pop. We try your eye, but can you change everything? I really like the colour but can you change it I know somebody who can do this for a reasonable cost I need a website. How much will it cost anyway, you are the designer, you know what to do, for is there a way we can make the page feel more introductory without being cheesy. Can my website be in english? can you turn it around in photoshop so we can see more of the front can you help me out? you will get a lot of free exposure doing this can you turn it around in photoshop so we can see more of the front can't you just take a picture from the internet?, use a kpop logo that's not a kpop logo! ugh you are lucky to even be doing this for us. I cant pay you can't you just take a picture from the internet? but try making it a bit less blah. It looks a bit empty, try to make everything bigger what you've given us is texty, we want sexy for can you make it look more designed can you punch up the fun level on these icons can you help me out? you will get a lot of free exposure doing this. Remember, everything is the same or better we have big contacts we will promote you, for use a kpop logo that's not a kpop logo! ugh. -I'll pay you in a week we don't need to pay upfront i hope you understand what is a hamburger menu and could you do an actual logo instead of a font, or is there a way we can make the page feel more introductory without being cheesy or I think we need to start from scratch, and anyway, you are the designer, you know what to do. Thats not what i saw in my head at all this red is too red try a more powerful colour concept is bang on, but can we look at a better execution give us a complimentary logo along with the website, I like it, but can the snow look a little warmer. Could you move it a tad to the left needs to be sleeker can my website be in english? this turned out different that i decscribed we need more images of groups of people having non-specific types of fun. Mmm, exactly like that, but different we are a non-profit organization can't you just take a picture from the internet? can you make it more infographic-y so I think we need to start from scratch make it pop. This turned out different that i decscribed doing some work for us "pro bono" will really add to your portfolio i promise. Im not sure, try something else i'll pay you in a week we don't need to pay upfront i hope you understand. -Is this the best we can do something summery; colourful, but mmm, exactly like that, but different. Doing some work for us "pro bono" will really add to your portfolio i promise i'll pay you in a week we don't need to pay upfront i hope you understand can you make the font bigger? can you turn it around in photoshop so we can see more of the front, yet could you do an actual logo instead of a font. Is there a way we can make the page feel more introductory without being cheesy this looks perfect. Just Photoshop out the dog, add a baby, and make the curtains blue, and labrador make it original low resolution? It looks ok on my screen. Could you rotate the picture to show the other side of the room?. Make it pop that's great, but can you make it work for ie 2 please make it pop i'll pay you in a week we don't need to pay upfront i hope you understand. Give us a complimentary logo along with the website. This was not according to brief will royalties in the company do instead of cash for can you put "find us on facebook" by the facebook logo?. I like it, but can the snow look a little warmer thanks for taking the time to make the website, but i already made it in wix can you make pink a little more pinkish can you make it look more designed , can you punch up the fun level on these icons or could you do an actual logo instead of a font. Make it original. We need more images of groups of people having non-specific types of fun can't you just take a picture from the internet? you are lucky to even be doing this for us nor that's going to be a chunk of change and I have an awesome idea for a startup, i need you to build it for me what you've given us is texty, we want sexy. I really think this could go viral can you make the logo bigger yes bigger bigger still the logo is too big or is there a way we can make the page feel more introductory without being cheesy I have printed it out, but the animated gif is not moving, or can you make the blue bluer?. Can you pimp this powerpoint, need more geometry patterns. Needs to be sleeker that's great, but we need to add this 2000 line essay that's great, but can you make it work for ie 2 please give us a complimentary logo along with the website. I like it, but can the snow look a little warmer that sandwich needs to be more playful, so can you lower the price for the website? make it high quality and please use html can you make the font a bit bigger and change it to times new roman? jazz it up a little bit make the picture of the cupcake look delicious make the purple more well, purple-er it looks so empty add some more hearts can you add a bit of pastel pink and baby blue because the purple alone looks too fancy okay can you put a cute quote on the right side of the site? oh no it looks messed up! i think we need to start from scratch. Remember, everything is the same or better could you move it a tad to the left. I'll know it when i see it could you do an actual logo instead of a font, and can we barter services? or can you make pink a little more pinkish. Are you busy this weekend? I have a new project with a tight deadline. Can we have another option what is a hamburger menu. Needs to be sleeker thanks for taking the time to make the website, but i already made it in wix so just do what you think. I trust you, yet can you use a high definition screenshot and needs to be sleeker, nor can you help me out? you will get a lot of free exposure doing this. You can get my logo from facebook i cant pay you can you make pink a little more pinkish other agencies charge much lesser this red is too red but in an ideal world. Can you make it more infographic-y this red is too red can you make it pop. Can you make the font bigger? make it pop and can we try some other colours maybe. I like it, but can the snow look a little warmer you can get my logo from facebook but can you make it faster? yet will royalties in the company do instead of cash the target audience is makes and famles aged zero and up. Can't you just take a picture from the internet? can you please send me the design specs again?, so can you help me out? you will get a lot of free exposure doing this nor that sandwich needs to be more playful this turned out different that i decscribed. We don't need a backup, it never goes down! can you lower the price for the website? make it high quality and please use html can you make the font a bit bigger and change it to times new roman? jazz it up a little bit make the picture of the cupcake look delicious make the purple more well, purple-er it looks so empty add some more hearts can you add a bit of pastel pink and baby blue because the purple alone looks too fancy okay can you put a cute quote on the right side of the site? oh no it looks messed up! i think we need to start from scratch. \ No newline at end of file diff --git a/examples/others/word_counter/ex6.txt b/examples/others/word_counter/ex6.txt deleted file mode 100644 index 4cc6030..0000000 --- a/examples/others/word_counter/ex6.txt +++ /dev/null @@ -1,14 +0,0 @@ -Breathe in your fears. Face them. To conquer fear, you must become fear. You must bask in the fear of other men. And men fear most what they cannot see. You have to become a terrible thought. A wraith. You have to become an idea! Feel terror cloud your senses. Feel its power to distort. To control. And know that this power can be yours. Embrace your worst fear. Become one with the darkness. -You wanna know how I got these scars? My father was... a drinker, and a fiend. And one night, he goes off crazier than usual. Mommy gets the kitchen knife to defend herself. He doesn't like that, not one bit. So, me watching he takes the knife to her, laughing while he does it. He turns to me and he says: "Why so serious?". He comes at me with the knife "Why so serious?". He sticks the blade in my mouth. "Let's put a smile on that face." and... Why so serious? -My name is Merely Ducard but I speak for Ra's al Ghul... a man greatly feared by the criminal underworld. A mon who can offer you a path. Someone like you is only here by choice. You have been exploring the criminal fraternity but whatever your original intentions you have to become truly lost. The path of a man who shares his hatred of evil and wishes to serve true justice. The path of the League of Shadows. -Every man who has lotted here over the centuries, has looked up to the light and imagined climbing to freedom. So easy, so simple! And like shipwrecked men turning to seawater foregoing uncontrollable thirst, many have died trying. And then here there can be no true despair without hope. So as I terrorize Gotham, I will feed its people hope to poison their souls. I will let them believe that they can survive so that you can watch them climbing over each other to stay in the sun. You can watch me torture an entire city. And then when you've truly understood the depth of your failure, we will fulfill Ra's Al Ghul's destiny. We will destroy Gotham. And then, when that is done, and Gotham is... ashes Then you have my permission to die. -But we've met before. That was a long time ago, I was a kid at St. Swithin's, It used to be funded by the Wayne Foundation. It's an orphanage. My mum died when I was small, it was a car accident. I don't remember it. My dad got shot a couple of years later for a gambling debt. Oh I remember that one just fine. Not a lot of people know what it feels like to be angry in your bones. I mean they understand. The fosters parents. Everybody understands, for a while. Then they want the angry little kid to do something he knows he can't do, move on. After a while they stop understanding. They send the angry kid to a boy's home, I figured it out too late. Yeah I learned to hide the anger, and practice smiling in the mirror. It's like putting on a mask. So you showed up this one day, in a cool car, pretty girl on your arm. We were so excited! Bruce Wayne, a billionaire orphan? We used to make up stories about you man, legends and you know with the other kids, that's all it was, just stories, but right when I saw you, I knew who you really were. I'd seen that look on your face before. It's the same one I taught myself. I don't why you took the fault for Dent's murder but I'm still a believer in the Batman. Even if you're not... -You wanna know how I got them? So I had a wife. She was beautiful, like you, who tells me I worry too much, who tells me I ought to smile more, who gambles and gets in deep with the sharks. Hey. One day they carve her face. And we have no money for surgeries. She can't take it. I just wanna see her smile again. I just want her to know that I don't care about the scars. So, I do this to myself. And you know what? She can't stand the sight of me. She leaves. Now I see the funny side. Now I'm always smiling. -Every year, I took a holiday. I went to Florence, this cafe on the banks of the Arno. Every fine evening, I would sit there and order a Fernet Branca. I had this fantasy, that I would look across the tables and I would see you there with a wife maybe a couple of kids. You wouldn't say anything to me, nor me to you. But we would both know that you've made it, that you were happy. I never wanted you to come back to Gotham. I always knew there was nothing here for you except pain and tragedy and I wanted something more for you than that. I still do. -Breathe in your fears. Face them. To conquer fear, you must become fear. You must bask in the fear of other men. And men fear most what they cannot see. You have to become a terrible thought. A wraith. You have to become an idea! Feel terror cloud your senses. Feel its power to distort. To control. And know that this power can be yours. Embrace your worst fear. Become one with the darkness. -You wanna know how I got these scars? My father was... a drinker, and a fiend. And one night, he goes off crazier than usual. Mommy gets the kitchen knife to defend herself. He doesn't like that, not one bit. So, me watching he takes the knife to her, laughing while he does it. He turns to me and he says: "Why so serious?". He comes at me with the knife "Why so serious?". He sticks the blade in my mouth. "Let's put a smile on that face." and... Why so serious? -My name is Merely Ducard but I speak for Ra's al Ghul... a man greatly feared by the criminal underworld. A mon who can offer you a path. Someone like you is only here by choice. You have been exploring the criminal fraternity but whatever your original intentions you have to become truly lost. The path of a man who shares his hatred of evil and wishes to serve true justice. The path of the League of Shadows. -Every man who has lotted here over the centuries, has looked up to the light and imagined climbing to freedom. So easy, so simple! And like shipwrecked men turning to seawater foregoing uncontrollable thirst, many have died trying. And then here there can be no true despair without hope. So as I terrorize Gotham, I will feed its people hope to poison their souls. I will let them believe that they can survive so that you can watch them climbing over each other to stay in the sun. You can watch me torture an entire city. And then when you've truly understood the depth of your failure, we will fulfill Ra's Al Ghul's destiny. We will destroy Gotham. And then, when that is done, and Gotham is... ashes Then you have my permission to die. -But we've met before. That was a long time ago, I was a kid at St. Swithin's, It used to be funded by the Wayne Foundation. It's an orphanage. My mum died when I was small, it was a car accident. I don't remember it. My dad got shot a couple of years later for a gambling debt. Oh I remember that one just fine. Not a lot of people know what it feels like to be angry in your bones. I mean they understand. The fosters parents. Everybody understands, for a while. Then they want the angry little kid to do something he knows he can't do, move on. After a while they stop understanding. They send the angry kid to a boy's home, I figured it out too late. Yeah I learned to hide the anger, and practice smiling in the mirror. It's like putting on a mask. So you showed up this one day, in a cool car, pretty girl on your arm. We were so excited! Bruce Wayne, a billionaire orphan? We used to make up stories about you man, legends and you know with the other kids, that's all it was, just stories, but right when I saw you, I knew who you really were. I'd seen that look on your face before. It's the same one I taught myself. I don't why you took the fault for Dent's murder but I'm still a believer in the Batman. Even if you're not... -You wanna know how I got them? So I had a wife. She was beautiful, like you, who tells me I worry too much, who tells me I ought to smile more, who gambles and gets in deep with the sharks. Hey. One day they carve her face. And we have no money for surgeries. She can't take it. I just wanna see her smile again. I just want her to know that I don't care about the scars. So, I do this to myself. And you know what? She can't stand the sight of me. She leaves. Now I see the funny side. Now I'm always smiling. -Every year, I took a holiday. I went to Florence, this cafe on the banks of the Arno. Every fine evening, I would sit there and order a Fernet Branca. I had this fantasy, that I would look across the tables and I would see you there with a wife maybe a couple of kids. You wouldn't say anything to me, nor me to you. But we would both know that you've made it, that you were happy. I never wanted you to come back to Gotham. I always knew there was nothing here for you except pain and tragedy and I wanted something more for you than that. I still do. \ No newline at end of file diff --git a/examples/printer.c b/examples/printer.c deleted file mode 100644 index 16667b7..0000000 --- a/examples/printer.c +++ /dev/null @@ -1,207 +0,0 @@ -// Prints a file in the terminal separated by pages - -#include "macro_collections.h" - -#define TAB_SIZE 4 -#define ROW_INI_CAP DOC_LETTERS_IN_ROW -#define DOC_LETTERS_IN_ROW 100 -#define DOC_ROWS_IN_PAGE 50 -#define DOC_MARGIN 4 - -C_MACRO_COLLECTIONS_ALL(CMC, LIST, (row, row, , , char)) -C_MACRO_COLLECTIONS_ALL(CMC, LIST, (doc, document, , , struct row *)) - -struct row_fval *row_funcs = &(struct row_fval){ NULL }; -struct document_fval *doc_funcs = &(struct document_fval){ .free = row_free }; - -struct document *document_load(const char *file_name); -void document_empty_line(FILE *fptr); -void document_page_outline(FILE *fptr, int outline); -void document_page_margin(FILE *fptr, int margin); -void document_print(struct document *doc, FILE *fptr); - -struct document *document_load(const char *file_name) -{ - FILE *file = fopen(file_name, "r"); - - if (!file) - { - cmc_log_error("File %s not found\n", file_name); - return NULL; - } - - struct row *initial_row = row_new(ROW_INI_CAP, row_funcs); - - struct document *doc = doc_new(100, doc_funcs); - doc_push_back(doc, initial_row); - - int ch; - - while ((ch = getc(file)) != EOF) - { - char c = (char)ch; - - struct row *current_row = doc_back(doc); - - if (c == '\n') - { - struct row *new_row = row_new(ROW_INI_CAP, row_funcs); - doc_push_back(doc, new_row); - } - else if (c == '\t') - { - intmax_t left = TAB_SIZE; - - while (left > 0 && row_count(current_row) < DOC_LETTERS_IN_ROW) - { - row_push_back(current_row, ' '); - left--; - } - - if (left > 0) - { - struct row *new_row = row_new(ROW_INI_CAP, row_funcs); - doc_push_back(doc, new_row); - - while (left > 0) - { - row_push_back(new_row, ' '); - left--; - } - } - } - else if (DOC_LETTERS_IN_ROW == row_count(current_row)) - { - struct row *new_row = row_new(ROW_INI_CAP, row_funcs); - row_push_back(new_row, c); - doc_push_back(doc, new_row); - } - else - row_push_back(current_row, c); - } - - return doc; -} - -void document_empty_line(FILE *fptr) -{ - fputs("\t|", fptr); - for (size_t i = 0; i < DOC_LETTERS_IN_ROW + DOC_MARGIN * 2; i++) - { - fputc(' ', fptr); - } - fputs("\t|\n", fptr); -} - -void document_page_outline(FILE *fptr, int outline /* 0 - header, 1 - footer */) -{ - if (outline == 1) - { - document_empty_line(fptr); -#ifdef DOC_PAGE_NUMBER - static intmax_t page = 1; - - fputs("\t|", fptr); - for (size_t i = 0; i < (DOC_LETTERS_IN_ROW + DOC_MARGIN) - 8; i++) - { - fputc(' ', fptr); - } - - fprintf(fptr, "%8" PRIdMAX "", page); - page++; - - document_page_margin(fptr, 1); - document_empty_line(fptr); -#endif - } - - fputs("\t+", fptr); - for (size_t i = 0; i < DOC_LETTERS_IN_ROW + DOC_MARGIN * 2 + 3; i++) - { - fputc('-', fptr); - } - fputs("+\n", fptr); - - if (outline == 0) - document_empty_line(fptr); -} - -void document_page_margin(FILE *fptr, int margin /* 0 - first margin, 1 - second margin */) -{ - if (margin == 0) - fputs("\t|", fptr); - - for (size_t i = 0; i < DOC_MARGIN; i++) - { - fputc(' ', fptr); - } - - if (margin == 1) - fputs("\t|\n", fptr); -} - -void document_print(struct document *doc, FILE *fptr) -{ - fputc('\n', fptr); - - intmax_t current_page_row = 0, total_rows = doc_count(doc); - - // Print document - for (intmax_t i = 0; i < total_rows; i++, current_page_row++) - { - if (current_page_row == 0) - document_page_outline(fptr, 0); - - struct row *current_row = doc_get(doc, i); - - if (!current_row) - cmc_log_fatal("Unexpected NULL pointer for %s", "current_row"); - - document_page_margin(fptr, 0); - - for (size_t k = 0; k < row_count(current_row); k++) - fputc(row_get(current_row, k), fptr); - - // Trailing margin - for (size_t k = 0; k < DOC_LETTERS_IN_ROW - row_count(current_row); k++) - fputc(' ', fptr); - - document_page_margin(fptr, 1); - - // Print the end of the page and reset - if (current_page_row == DOC_ROWS_IN_PAGE - 1) - { - document_page_outline(fptr, 1); - current_page_row = -1; - fputc('\n', fptr); - } - } - - // Print trailing page - if (total_rows % DOC_ROWS_IN_PAGE != 0) - { - for (size_t i = 0; i < DOC_ROWS_IN_PAGE - current_page_row; i++) - document_empty_line(fptr); - - document_page_outline(fptr, 1); - } - - fputc('\n', fptr); -} - -int main(int argc, char const *argv[]) -{ - if (argc != 2) - { - cmc_log_error("Please define one argument only for %s", argv[0]); - return 1; - } - - struct document *doc = document_load(argv[1]); - - document_print(doc, stdout); - - doc_free(doc); - - return 0; -} diff --git a/examples/queue/README.md b/examples/queue/README.md deleted file mode 100644 index 128078a..0000000 --- a/examples/queue/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Queue examples - -* ice_cream.c - Example of what happens when you get late to the queue and the ice creams are sold out! -* iterator.c - A complete example of the queue iterator diff --git a/examples/queue/ice_cream.c b/examples/queue/ice_cream.c deleted file mode 100644 index 1e55a60..0000000 --- a/examples/queue/ice_cream.c +++ /dev/null @@ -1,79 +0,0 @@ -/** - * ice_cream.c - * - * Creation Date: 03/04/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ -#include "cmc/queue.h" -#include -#include -#include - -CMC_GENERATE_QUEUE(q, queue, const char *); -typedef struct queue queue; -typedef struct queue_iter queue_iter; - - -int main(int argc, char const *argv[]) -{ - srand((unsigned)time(NULL)); - - // 1- People are lining up to get some ice cream but there is not enough - // for everyone! Hurry! Get in the queue! - - size_t total_icecreams = 20; - - queue *lineup = q_new(10); - - q_enqueue(lineup, "Albert"); - q_enqueue(lineup, "Newton"); - q_enqueue(lineup, "Marie"); - q_enqueue(lineup, "Charles"); - q_enqueue(lineup, "Nikola"); - q_enqueue(lineup, "Thomas"); - q_enqueue(lineup, "Niels"); - q_enqueue(lineup, "Galileo"); - q_enqueue(lineup, "Stephen"); - q_enqueue(lineup, "Leonardo"); - q_enqueue(lineup, "Max"); - q_enqueue(lineup, "Dmitri"); - - while (total_icecreams > 0) - { - size_t catch = rand() % 5; - - const char *name = q_peek(lineup); - - if (!q_dequeue(lineup)) - break; - - printf("%-8s got %lu ice cream(s) from the ice cream truck\n", name, catch); - - total_icecreams = catch > total_icecreams ? 0 : total_icecreams - catch; - } - - if (!q_empty(lineup)) - { - printf("\nOh no! Someone didn't get their ice cream!\n\n"); - - while (!q_empty(lineup)) - { - const char *name = q_peek(lineup); - - q_dequeue(lineup); - - printf("%-8s got no ice cream and he is sad\n", name); - } - } - else if (total_icecreams > 0) - { - printf("\n%lu ice creams remaining to be sold on the next day.\n"); - } - - q_free(lineup, NULL); - - return 0; -} diff --git a/examples/queue/iterator.c b/examples/queue/iterator.c deleted file mode 100644 index 377b2e4..0000000 --- a/examples/queue/iterator.c +++ /dev/null @@ -1,198 +0,0 @@ -/** - * iterator.c - * - * Creation Date: 15/05/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - * Iterator Example - */ -#include "cmc/queue.h" -#include -#include - -// Creates a queue of integers -CMC_GENERATE_QUEUE(q, queue, int); -typedef struct queue queue; -typedef struct queue_iter queue_iter; - - -int main(int argc, char const *argv[]) -{ - // Create a new queue with an initial capacity of 100 - queue *my_queue = q_new(100); - - // Add elements to the queue - for (int i = 0; i < 20; i++) - { - q_enqueue(my_queue, i); - } - - // Iterate from the start (front) to the end (rear) of the queue - for (queue_iter it = my_queue->it_start(my_queue); // Initialize iterator 'it' to the start of the queue - !q_iter_end(&it); // Conditional stop (until it is not at the end) - q_iter_next(&it)) // Iterator goes one position forward - { - // Access the current element - int e = q_iter_value(&it); - - // Access the current index (index is relative to all the elements in the iteration) - size_t i = q_iter_index(&it); - - // Print queue - - // Index is useful in situations like this - // If it is the first element - if (i == 0) - printf("[ %d, ", e); - // If it is the last element - else if (i == q_count(my_queue) - 1) - printf("%d ]\n", e); - // For elements at the middle - else - printf("%d, ", e); - } - - // Index can also be used to iterate over a certain portion of a collection - size_t limit = q_count(my_queue) / 2; - for (queue_iter it = my_queue->it_start(my_queue); !q_iter_end(&it); q_iter_next(&it)) - { - // Access the current element - int e = q_iter_value(&it); - - // Access the current index (index is relative to all the elements in the iteration) - size_t i = q_iter_index(&it); - - // Print queue up until limit - - // If it is the first element - if (i == 0) - printf("[ %d, ", e); - // If it is the last element - else if (i == limit - 1) // -1 because index is 0 based and we want half of the queue - { - printf("%d ]\n", e); - break; - } - // For elements at the middle - else - printf("%d, ", e); - } - - // Going backwards - for (queue_iter it = my_queue->it_end(my_queue); // Initialize iterator 'it' to the end of the queue - !q_iter_start(&it); // Conditional stop (until it is not at the start) - q_iter_prev(&it)) // Iterator goes one position backwards - { - // Access the current element - int e = q_iter_value(&it); - - // Access the current index (index is relative to all the elements in the iteration) - size_t i = q_iter_index(&it); - - // Print queue - // Note how the conditions for the first and last elements are simply swapped - // Because iterating backwards make the first element be the index count - 1 - // and the last one be the index 0 - - // If it is the first element - if (i == q_count(my_queue) - 1) - printf("[ %d, ", e); - // If it is the last element - else if (i == 0) - printf("%d ]\n", e); - // For elements at the middle - else - printf("%d, ", e); - } - - // You can also use iterators in a while loop - // But to do so you must declare the iterator struct outside the loop first - queue_iter it; - - // You have three options: - // - Initialize it using the functions provided by the queue [ my_queue->it_start() and my_queue->it_end() ] - // - Initialize it using the init() function (when the iterator is already allocated) - // - Initialize it using the new() function (allocates on the heap, pointers only) - - it = my_queue->it_start(my_queue); - it = my_queue->it_end(my_queue); - - // This is equivalent to it_start() - q_iter_init(&it, my_queue); - - // For pointers - // Also equivalent to it_start() - queue_iter *iter = q_iter_new(my_queue); - - // The actual while loop - while (!q_iter_end(iter)) - { - // Accessing elements - int e = q_iter_value(iter); - size_t i = q_iter_index(iter); - - // Print index and element - printf("queue[%2" PRIuMAX "] = %2d\n", i, e); - - // Move iterator forwards - q_iter_next(iter); - } - - // Send the iterator to the start of the queue - q_iter_to_start(iter); - - // Send the iterator to the end of the queue - q_iter_to_end(iter); - - // Backwards loop - while (!q_iter_start(iter)) - { - // Accessing elements - int e = q_iter_value(iter); - size_t i = q_iter_index(iter); - - // Print index and element - printf("queue[%2" PRIuMAX "] = %2d\n", i, e); - - // Move iterator backwards - q_iter_prev(iter); - } - - // Certain iterators also allow you to modify the contents it is iterating over - // Exceptions are collections that depend of the current state of the element - // like tree-based collections and heap (collections that have some kind of ordering). - // You also can't change the keys of an associative collection - - // Change every element that is divisible by 3 to the number 7 - for (q_iter_to_start(&it); !q_iter_end(&it); q_iter_next(&it)) - { - // Get a reference to the current value - int *r = q_iter_rvalue(&it); - - if (r != NULL && *r % 3 == 0) - *r = 7; - } - - // Now print it to see the difference - for (queue_iter it = my_queue->it_start(my_queue); !q_iter_end(&it); q_iter_next(&it)) - { - int e = q_iter_value(&it); - size_t i = q_iter_index(&it); - - if (i == 0) - printf("[ %d, ", e); - else if (i == q_count(my_queue) - 1) - printf("%d ]\n", e); - else - printf("%d, ", e); - } - - // Dispose the iterator called by q_iter_new() - q_iter_free(iter); - // Dispose the queue created - q_free(my_queue, NULL); - - return 0; -} diff --git a/examples/sieve.c b/examples/sieve.c deleted file mode 100644 index 12f681a..0000000 --- a/examples/sieve.c +++ /dev/null @@ -1,42 +0,0 @@ -#include "cmc/bitset.h" -#include - -CMC_CMC_BITSET_CORE(PUBLIC, HEADER, (bs, bitset)) -CMC_CMC_BITSET_CORE(PUBLIC, SOURCE, (bs, bitset)) - -// All the prime numbers up to 1 billion -// With -O3: -// 28.583 s runtime -// 120 MB RAM -// 490 MB file size -int main(void) -{ - const size_t n = 1000000000; - - struct bitset *set = bs_new(n); - - if (!set) - return 1; - - bs_set_range(set, 0, n); - - size_t up_to = sqrt((double)n) + 1; - for (size_t i = 2; i < up_to; ++i) - { - if (bs_get(set, i)) - { - for (size_t j = 2 * i; j < n; j += i) - bs_clear(set, j); - } - } - - FILE *file = fopen("primes.txt", "w"); - - for (size_t i = 2; i < n; i++) - { - if (bs_get(set, i)) - fprintf(file, "%" PRIuMAX " ", i); - } - - fclose(file); -} diff --git a/examples/stack/README.md b/examples/stack/README.md deleted file mode 100644 index cb88b71..0000000 --- a/examples/stack/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Stack examples - -* hanoi.c - Animated example of solving the hanoi tower. -* iterator.c - A complete example of the stack iterator diff --git a/examples/stack/hanoi.c b/examples/stack/hanoi.c deleted file mode 100644 index 7f05832..0000000 --- a/examples/stack/hanoi.c +++ /dev/null @@ -1,111 +0,0 @@ -/** - * hanoi.c - * - * Creation Date: 03/04/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ -#include "cmc/stack.h" -#include -#include - -CMC_GENERATE_STACK(s, stack, int); -typedef struct stack stack; -typedef struct stack_iter stack_iter; - - -void print_hanoi(stack *t1, stack *t2, stack *t3); -const char *draw(int value); -void move_disc(stack *from, stack *to); -void move_stack(stack *t1, stack *t2, stack *t3, size_t size); - -int main(int argc, char const *argv[]) -{ - // 1- Hanoi towers showcase - - stack *tower1 = s_new(10); - stack *tower2 = s_new(10); - stack *tower3 = s_new(10); - - for (int i = 10; i > 0; i--) - s_push(tower1, i); - - move_stack(tower1, tower3, tower2, s_count(tower1)); - - s_free(tower1, NULL); - s_free(tower2, NULL); - s_free(tower3, NULL); - - return 0; -} - -void print_hanoi(stack *t1, stack *t2, stack *t3) -{ - const int max = 10; - - static int step = 0; - printf("Step %d\n", ++step); - - for (int i = max - 1; i >= 0; i--) - { - - printf(" %10s|%-10s %10s|%-10s %10s|%-10s\n", - draw(t1->buffer[i]), draw(t1->buffer[i]), - draw(t2->buffer[i]), draw(t2->buffer[i]), - draw(t3->buffer[i]), draw(t3->buffer[i])); - } - printf(" ----------------------- ----------------------- -----------------------\n\n"); -} - -const char *draw(int value) -{ - switch (value) - { - case 0: - return ""; - case 1: - return "#"; - case 2: - return "##"; - case 3: - return "###"; - case 4: - return "####"; - case 5: - return "#####"; - case 6: - return "######"; - case 7: - return "#######"; - case 8: - return "########"; - case 9: - return "#########"; - case 10: - return "##########"; - default: - return "?"; - } -} - -void move_disc(stack *from, stack *to) -{ - s_push(to, s_top(from)); - s_pop(from); -} - -void move_stack(stack *t1, stack *t2, stack *t3, size_t size) -{ - if (size == 0) - return; - - move_stack(t1, t3, t2, size - 1); - - move_disc(t1, t2); - - print_hanoi(t1, t2, t3); - - move_stack(t3, t2, t1, size - 1); -} diff --git a/examples/stack/iterator.c b/examples/stack/iterator.c deleted file mode 100644 index c7074f3..0000000 --- a/examples/stack/iterator.c +++ /dev/null @@ -1,198 +0,0 @@ -/** - * iterator.c - * - * Creation Date: 15/05/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - * Iterator Example - */ -#include "cmc/stack.h" -#include -#include - -// Creates a stack of integers -CMC_GENERATE_STACK(s, stack, int); -typedef struct stack stack; -typedef struct stack_iter stack_iter; - - -int main(int argc, char const *argv[]) -{ - // Create a new stack with an initial capacity of 100 - stack *my_stack = s_new(100); - - // Add elements to the stack - for (int i = 0; i < 20; i++) - { - s_push(my_stack, i); - } - - // Iterate from the start (top) to the end (bottom) of the stack - for (stack_iter it = my_stack->it_start(my_stack); // Initialize iterator 'it' to the start of the stack - !s_iter_end(&it); // Conditional stop (until it is not at the end) - s_iter_next(&it)) // Iterator goes one position forward - { - // Access the current element - int e = s_iter_value(&it); - - // Access the current index (index is relative to all the elements in the iteration) - size_t i = s_iter_index(&it); - - // Print stack - - // Index is useful in situations like this - // If it is the first element - if (i == 0) - printf("[ %d, ", e); - // If it is the last element - else if (i == s_count(my_stack) - 1) - printf("%d ]\n", e); - // For elements at the middle - else - printf("%d, ", e); - } - - // Index can also be used to iterate over a certain portion of a collection - size_t limit = s_count(my_stack) / 2; - for (stack_iter it = my_stack->it_start(my_stack); !s_iter_end(&it); s_iter_next(&it)) - { - // Access the current element - int e = s_iter_value(&it); - - // Access the current index (index is relative to all the elements in the iteration) - size_t i = s_iter_index(&it); - - // Print stack up until limit - - // If it is the first element - if (i == 0) - printf("[ %d, ", e); - // If it is the last element - else if (i == limit - 1) // -1 because index is 0 based and we want half of the stack - { - printf("%d ]\n", e); - break; - } - // For elements at the middle - else - printf("%d, ", e); - } - - // Going backwards - for (stack_iter it = my_stack->it_end(my_stack); // Initialize iterator 'it' to the end of the stack - !s_iter_start(&it); // Conditional stop (until it is not at the start) - s_iter_prev(&it)) // Iterator goes one position backwards - { - // Access the current element - int e = s_iter_value(&it); - - // Access the current index (index is relative to all the elements in the iteration) - size_t i = s_iter_index(&it); - - // Print stack - // Note how the conditions for the first and last elements are simply swapped - // Because iterating backwards make the first element be the index count - 1 - // and the last one be the index 0 - - // If it is the first element - if (i == s_count(my_stack) - 1) - printf("[ %d, ", e); - // If it is the last element - else if (i == 0) - printf("%d ]\n", e); - // For elements at the middle - else - printf("%d, ", e); - } - - // You can also use iterators in a while loop - // But to do so you must declare the iterator struct outside the loop first - stack_iter it; - - // You have three options: - // - Initialize it using the functions provided by the stack [ my_stack->it_start() and my_stack->it_end() ] - // - Initialize it using the init() function (when the iterator is already allocated) - // - Initialize it using the new() function (allocates on the heap, pointers only) - - it = my_stack->it_start(my_stack); - it = my_stack->it_end(my_stack); - - // This is equivalent to it_start() - s_iter_init(&it, my_stack); - - // For pointers - // Also equivalent to it_start() - stack_iter *iter = s_iter_new(my_stack); - - // The actual while loop - while (!s_iter_end(iter)) - { - // Accessing elements - int e = s_iter_value(iter); - size_t i = s_iter_index(iter); - - // Print index and element - printf("stack[%2" PRIuMAX "] = %2d\n", i, e); - - // Move iterator forwards - s_iter_next(iter); - } - - // Send the iterator to the start of the stack - s_iter_to_start(iter); - - // Send the iterator to the end of the stack - s_iter_to_end(iter); - - // Backwards loop - while (!s_iter_start(iter)) - { - // Accessing elements - int e = s_iter_value(iter); - size_t i = s_iter_index(iter); - - // Print index and element - printf("stack[%2" PRIuMAX "] = %2d\n", i, e); - - // Move iterator backwards - s_iter_prev(iter); - } - - // Certain iterators also allow you to modify the contents it is iterating over - // Exceptions are collections that depend of the current state of the element - // like tree-based collections and heap (collections that have some kind of ordering). - // You also can't change the keys of an associative collection - - // Change every element that is divisible by 3 to the number 7 - for (s_iter_to_start(&it); !s_iter_end(&it); s_iter_next(&it)) - { - // Get a reference to the current value - int *r = s_iter_rvalue(&it); - - if (r != NULL && *r % 3 == 0) - *r = 7; - } - - // Now print it to see the difference - for (stack_iter it = my_stack->it_start(my_stack); !s_iter_end(&it); s_iter_next(&it)) - { - int e = s_iter_value(&it); - size_t i = s_iter_index(&it); - - if (i == 0) - printf("[ %d, ", e); - else if (i == s_count(my_stack) - 1) - printf("%d ]\n", e); - else - printf("%d, ", e); - } - - // Dispose the iterator called by s_iter_new() - s_iter_free(iter); - // Dispose the stack created - s_free(my_stack, NULL); - - return 0; -} diff --git a/examples/treemap/README.md b/examples/treemap/README.md deleted file mode 100644 index 0bc53dd..0000000 --- a/examples/treemap/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Treemap examples - -* pseudo_multiset.c - An example of how to make a multiset using a map. -* iterator.c - A complete example of the treemap iterator diff --git a/examples/treemap/iterator.c b/examples/treemap/iterator.c deleted file mode 100644 index 32feb9f..0000000 --- a/examples/treemap/iterator.c +++ /dev/null @@ -1,220 +0,0 @@ -/** - * iterator.c - * - * Creation Date: 16/05/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - * Iterator Example - */ -#include "cmc/treemap.h" -#include -#include - -// Int compare function -int intcmp(int a, int b) -{ - return a - b; -} - -// Creates a treemap of integers -CMC_GENERATE_TREEMAP(tm, treemap, int, double); -typedef struct treemap treemap; -typedef struct treemap_iter treemap_iter; - - -int main(int argc, char const *argv[]) -{ - // Create a new treemap - treemap *my_map = tm_new(intcmp); - - // Add pairs to the treemap - for (int i = 0; i < 20; i++) - { - // Map integers to doubles - tm_insert(my_map, i, (double)i / 10.0); - } - - // Iterate from the start (left-most node) to the end (right-most node) of the treemap - for (treemap_iter it = my_map->it_start(my_map); // Initialize iterator 'it' to the start of the treemap - !tm_iter_end(&it); // Conditional stop (until it is not at the end) - tm_iter_next(&it)) // Iterator goes one position forward - { - // Access the current key - int k = tm_iter_key(&it); - - // Access the current value - double v = tm_iter_value(&it); - - // Access the current index (index is relative to all the pairs in the iteration) - size_t i = tm_iter_index(&it); - - // Print treemap - - // Index is useful in situations like this - // If it is the first pair - if (i == 0) - printf("[ {%d:%.2lf}, ", k, v); - // If it is the last pair - else if (i == tm_count(my_map) - 1) - printf("{%d:%.2lf} ]\n", k, v); - // For pairs at the middle - else - printf("{%d:%.2lf}, ", k, v); - } - - // Index can also be used to iterate over a certain portion of a collection - size_t limit = tm_count(my_map) / 2; - for (treemap_iter it = my_map->it_start(my_map); !tm_iter_end(&it); tm_iter_next(&it)) - { - // Access the current key - int k = tm_iter_key(&it); - - // Access the current value - double v = tm_iter_value(&it); - - // Access the current index (index is relative to all the pairs in the iteration) - size_t i = tm_iter_index(&it); - - // Print treemap up until limit - - // If it is the first pair - if (i == 0) - printf("[ {%d:%.2lf}, ", k, v); - // If it is the last pair - else if (i == limit - 1) // -1 because index is 0 based and we want half of the treemap - { - printf("{%d:%.2lf} ]\n", k, v); - break; - } - // For pairs at the middle - else - printf("{%d:%.2lf}, ", k, v); - } - - // Going backwards - for (treemap_iter it = my_map->it_end(my_map); // Initialize iterator 'it' to the end of the treemap - !tm_iter_start(&it); // Conditional stop (until it is not at the start) - tm_iter_prev(&it)) // Iterator goes one position backwards - { - // Access the current key - int k = tm_iter_key(&it); - - // Access the current value - double v = tm_iter_value(&it); - - // Access the current index (index is relative to all the pairs in the iteration) - size_t i = tm_iter_index(&it); - - // Print treemap - // Note how the conditions for the first and last pairs are simply swapped - // Because iterating backwards make the first pair be the index count - 1 - // and the last one be the index 0 - - // If it is the first pair - if (i == tm_count(my_map) - 1) - printf("[ {%d:%.2lf}, ", k, v); - // If it is the last pair - else if (i == 0) - printf("{%d:%.2lf} ]\n", k, v); - // For pairs at the middle - else - printf("{%d:%.2lf}, ", k, v); - } - - // You can also use iterators in a while loop - // But to do so you must declare the iterator struct outside the loop first - treemap_iter it; - - // You have three options: - // - Initialize it using the functions provided by the treemap [ my_map->it_start() and my_map->it_end() ] - // - Initialize it using the init() function (when the iterator is already allocated) - // - Initialize it using the new() function (allocates on the heap, pointers only) - - it = my_map->it_start(my_map); - it = my_map->it_end(my_map); - - // This is equivalent to it_start() - tm_iter_init(&it, my_map); - - // For pointers - // Also equivalent to it_start() - treemap_iter *iter = tm_iter_new(my_map); - - // The actual while loop - while (!tm_iter_end(iter)) - { - // Accessing pairs - int k = tm_iter_key(iter); - double v = tm_iter_value(iter); - size_t i = tm_iter_index(iter); - - // Print index and key value pair - printf("treemap[%2" PRIuMAX "] = { %2d : %.2lf }\n", i, k, v); - - // Move iterator forwards - tm_iter_next(iter); - } - - // Send the iterator to the start of the treemap - tm_iter_to_start(iter); - - // Send the iterator to the end of the treemap - tm_iter_to_end(iter); - - // Backwards loop - while (!tm_iter_start(iter)) - { - // Accessing pairs - int k = tm_iter_key(iter); - double v = tm_iter_value(iter); - size_t i = tm_iter_index(iter); - - // Print index and the key value pair - printf("treemap[%2" PRIuMAX "] = { %2d : %.2lf }\n", i, k, v); - - // Move iterator backwards - tm_iter_prev(iter); - } - - // Certain iterators also allow you to modify the contents it is iterating over - // Exceptions are collections that depend of the current state of the pair - // like tree-based collections and heap (collections that have some kind of ordering). - // You also can't change the keys of an associative collection - - // Change every value where its key is divisible by 3 to the number 7 - for (tm_iter_to_start(&it); !tm_iter_end(&it); tm_iter_next(&it)) - { - // Get current key - int k = tm_iter_key(&it); - - // Get a reference to the current value - double *v = tm_iter_rvalue(&it); - - if (k % 3 == 0) - *v = 7; - } - - // Now print it to see the difference - for (treemap_iter it = my_map->it_start(my_map); !tm_iter_end(&it); tm_iter_next(&it)) - { - int k = tm_iter_key(&it); - double v = tm_iter_value(&it); - size_t i = tm_iter_index(&it); - - if (i == 0) - printf("[ {%d:%.2lf}, ", k, v); - else if (i == tm_count(my_map) - 1) - printf("{%d:%.2lf} ]\n", k, v); - else - printf("{%d:%.2lf}, ", k, v); - } - - // Dispose the iterator called by tm_iter_new() - tm_iter_free(iter); - // Dispose the treemap created - tm_free(my_map, NULL); - - return 0; -} diff --git a/examples/treemap/pseudo_multiset.c b/examples/treemap/pseudo_multiset.c deleted file mode 100644 index 984d666..0000000 --- a/examples/treemap/pseudo_multiset.c +++ /dev/null @@ -1,90 +0,0 @@ -/** - * pseudo_multiset.c - * - * Creation Date: 26/04/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -// How to make a multiset using a map - -#include "cmc/treemap.h" -#include -#include - -// Mapping an integer by size_t which will represent the key's multiplicity -// (key could be anything and multiplicity could be an integer, preferably -// unsigned) -CMC_GENERATE_TREEMAP(tm, tmap, int, size_t); -typedef struct tmap tmap; -typedef struct tmap_iter tmap_iter; -typedef struct tmap_node tmap_node; - - -// Compare function used by the treemap -int intcmp(int a, int b) -{ - return (a > b) - (a < b); -} - -// Little helper to print the tree -void print_tree(tmap_node *root, int height) -{ - if (!root) - return; - - print_tree(root->right, height + 1); - - for (int i = 0; i < height; i++) - printf("|------- "); - - // Key:Multiplicity - printf("%d:%" PRIuMAX "\n", root->key, root->value); - - print_tree(root->left, height + 1); -} - -int main(int argc, char const *argv[]) -{ - tmap *map = tm_new(intcmp); - - // Start adding elements - for (int i = 0; i < 100; i++) - { - // Modulo of 8 so we get some repetition - int key = i % 8; - - // Get the reference to a value in the map with the key - size_t *rvalue = tm_get_ref(map, key); - - // If the key exists, rvalue is not null - if (rvalue != NULL) - { - // Incrementing it means we have added another key to the set - // The value represents the multiplicity, that is, how many times - // we have added the key in the set - (*rvalue)++; - } - else - // Create a new entry with key with an initial multiplicity of 1 - tm_insert(map, key, 1); - } - - print_tree(map->root, 0); - - // Summary - printf("\n---------- SUMMARY ----------\n\n"); - - // Print using iterator - for (tmap_iter it = map->it_start(map); !tm_iter_end(&it); tm_iter_next(&it)) - { - // Map[key] = multiplicity - printf("Map[%2d] = %" PRIuMAX "\n", tm_iter_key(&it), tm_iter_value(&it)); - } - - tm_free(map, NULL); - - return 0; -} diff --git a/examples/treeset/README.md b/examples/treeset/README.md deleted file mode 100644 index 84699b0..0000000 --- a/examples/treeset/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Treeset examples - -* iterator.c - A complete example of the treeset iterator -* set_ops.c - Demonstrates common set operations like *union*, *intersection*, *difference* and *symmetric difference*. -* tree_print.c - How to print a binary tree. diff --git a/examples/treeset/iterator.c b/examples/treeset/iterator.c deleted file mode 100644 index ea968e3..0000000 --- a/examples/treeset/iterator.c +++ /dev/null @@ -1,197 +0,0 @@ -/** - * iterator.c - * - * Creation Date: 16/05/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - * Iterator Example - */ -#include "cmc/treeset.h" -#include -#include - -// Int hash function -size_t inthash(int t) -{ - size_t a = t; - a += ~(a << 15); - a ^= (a >> 10); - a += (a << 3); - a ^= (a >> 6); - a += ~(a << 11); - a ^= (a >> 16); - return a; -} - -// Int compare function -int intcmp(int a, int b) -{ - return a - b; -} - -// Creates a treeset of integers -CMC_GENERATE_TREESET(ts, treeset, int); -typedef struct treeset treeset; -typedef struct treeset_iter treeset_iter; - - -int main(int argc, char const *argv[]) -{ - // Create a new treeset with an initial capacity of 100 and load factor of 0.6 - treeset *my_treeset = ts_new(intcmp); - - // Add elements to the treeset - for (int i = 0; i < 20; i++) - { - ts_insert(my_treeset, i); - } - - // Iterate from the start (index 0) to the end (index count - 1) of the treeset - for (treeset_iter it = my_treeset->it_start(my_treeset); // Initialize iterator 'it' to the start of the treeset - !ts_iter_end(&it); // Conditional stop (until it is not at the end) - ts_iter_next(&it)) // Iterator goes one position forward - { - // Access the current element - int e = ts_iter_value(&it); - - // Access the current index (index is relative to all the elements in the iteration) - size_t i = ts_iter_index(&it); - - // Print treeset - - // Index is useful in situations like this - // If it is the first element - if (i == 0) - printf("[ %d, ", e); - // If it is the last element - else if (i == ts_count(my_treeset) - 1) - printf("%d ]\n", e); - // For elements at the middle - else - printf("%d, ", e); - } - - // Index can also be used to iterate over a certain portion of a collection - size_t limit = ts_count(my_treeset) / 2; - for (treeset_iter it = my_treeset->it_start(my_treeset); !ts_iter_end(&it); ts_iter_next(&it)) - { - // Access the current element - int e = ts_iter_value(&it); - - // Access the current index (index is relative to all the elements in the iteration) - size_t i = ts_iter_index(&it); - - // Print treeset up until limit - - // If it is the first element - if (i == 0) - printf("[ %d, ", e); - // If it is the last element - else if (i == limit - 1) // -1 because index is 0 based and we want half of the treeset - { - printf("%d ]\n", e); - break; - } - // For elements at the middle - else - printf("%d, ", e); - } - - // Going backwards - for (treeset_iter it = my_treeset->it_end(my_treeset); // Initialize iterator 'it' to the end of the treeset - !ts_iter_start(&it); // Conditional stop (until it is not at the start) - ts_iter_prev(&it)) // Iterator goes one position backwards - { - // Access the current element - int e = ts_iter_value(&it); - - // Access the current index (index is relative to all the elements in the iteration) - size_t i = ts_iter_index(&it); - - // Print treeset - // Note how the conditions for the first and last elements are simply swapped - // Because iterating backwards make the first element be the index count - 1 - // and the last one be the index 0 - - // If it is the first element - if (i == ts_count(my_treeset) - 1) - printf("[ %d, ", e); - // If it is the last element - else if (i == 0) - printf("%d ]\n", e); - // For elements at the middle - else - printf("%d, ", e); - } - - // You can also use iterators in a while loop - // But to do so you must declare the iterator struct outside the loop first - treeset_iter it; - - // You have three options: - // - Initialize it using the functions provided by the treeset [ my_treeset->it_start() and my_treeset->it_end() ] - // - Initialize it using the init() function (when the iterator is already allocated) - // - Initialize it using the new() function (allocates on the heap, pointers only) - - it = my_treeset->it_start(my_treeset); - it = my_treeset->it_end(my_treeset); - - // This is equivalent to it_start() - ts_iter_init(&it, my_treeset); - - // For pointers - // Also equivalent to it_start() - treeset_iter *iter = ts_iter_new(my_treeset); - - // The actual while loop - while (!ts_iter_end(iter)) - { - // Accessing elements - int e = ts_iter_value(iter); - size_t i = ts_iter_index(iter); - - // Print index and element - printf("treeset[%2" PRIuMAX "] = %2d\n", i, e); - - // Move iterator forwards - ts_iter_next(iter); - } - - // Send the iterator to the start of the treeset - ts_iter_to_start(iter); - - // Send the iterator to the end of the treeset - ts_iter_to_end(iter); - - // Backwards loop - while (!ts_iter_start(iter)) - { - // Accessing elements - int e = ts_iter_value(iter); - size_t i = ts_iter_index(iter); - - // Print index and element - printf("treeset[%2" PRIuMAX "] = %2d\n", i, e); - - // Move iterator backwards - ts_iter_prev(iter); - } - - // Certain iterators also allow you to modify the contents it is iterating over - // Exceptions are collections that depend of the current state of the element - // like tree-based collections and heap (collections that have some kind of ordering). - // You also can't change the keys of an associative collection - - // In the case of a treeset or any set, this is not possible because the - // values of a set are its keys. Changing the elements could cause the set - // to be in an invalid state. - - // Dispose the iterator called by ts_iter_new() - ts_iter_free(iter); - // Dispose the treeset created - ts_free(my_treeset, NULL); - - return 0; -} diff --git a/examples/treeset/set_ops.c b/examples/treeset/set_ops.c deleted file mode 100644 index 602daf6..0000000 --- a/examples/treeset/set_ops.c +++ /dev/null @@ -1,106 +0,0 @@ -/** - * set_ops.c - * - * Creation Date: 27/03/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -// Demonstration of set operations like: -// - Union -// - Intersection -// - Difference -// - Symmetric Difference - -#include "cmc/treeset.h" -#include -#include - -CMC_GENERATE_TREESET(set, set, int); -typedef struct set set; -typedef struct set_iter set_iter; - - -void print_set(set *s) -{ - set_iter iter; - set_iter_init(&iter, s); - for (set_iter_to_start(&iter); !set_iter_end(&iter); set_iter_next(&iter)) - { - int result = set_iter_value(&iter); - size_t index = set_iter_index(&iter); - - if (index == 0) - printf("[ %2d, ", result); - else if (index == s->count - 1) - printf("%2d ]\n", result); - else - printf("%2d, ", result); - } -} - -int intcmp(int a, int b) -{ - return a - b; -} - -int main(int argc, char const *argv[]) -{ - set *set1 = set_new(intcmp); - set *set2 = set_new(intcmp); - - for (int i = 1; i <= 20; i++) - set_insert(set1, i); - - for (int i = 11; i <= 30; i++) - set_insert(set2, i); - - set *set3 = set_union(set1, set2); - - print_set(set1); - printf("UNION\n"); - print_set(set2); - printf("=\n"); - print_set(set3); - - printf("\n\n"); - - set *set4 = set_intersection(set1, set2); - - print_set(set1); - printf("INTERSECTION\n"); - print_set(set2); - printf("=\n"); - print_set(set4); - - printf("\n\n"); - - set *set5 = set_difference(set1, set2); - - print_set(set1); - printf("DIFFERENCE\n"); - print_set(set2); - printf("=\n"); - print_set(set5); - - printf("\n\n"); - - set *set6 = set_symmetric_difference(set1, set2); - - print_set(set1); - printf("SYMMETRIC DIFFERENCE\n"); - print_set(set2); - printf("=\n"); - print_set(set6); - - set_free(set1, NULL); - set_free(set2, NULL); - set_free(set3, NULL); - set_free(set4, NULL); - set_free(set5, NULL); - set_free(set6, NULL); - - return 0; -} diff --git a/examples/treeset/tree_print.c b/examples/treeset/tree_print.c deleted file mode 100644 index b65a7d9..0000000 --- a/examples/treeset/tree_print.c +++ /dev/null @@ -1,55 +0,0 @@ -/** - * tree_print.c - * - * Creation Date: 27/03/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ -#include "cmc/treeset.h" -#include -#include -#include - -CMC_GENERATE_TREESET(set, set, int); -typedef struct set set; -typedef struct set_iter set_iter; -typedef struct set_node set_node; - - -void print_tree(set_node *root, int height) -{ - if (!root) - return; - - print_tree(root->right, height + 1); - - for (int i = 0; i < height; i++) - printf("|------- "); - - printf("%d\n", root->value); - - print_tree(root->left, height + 1); -} - -int intcmp(int a, int b) -{ - return a - b; -} - -int main(int argc, char const *argv[]) -{ - set *set1 = set_new(intcmp); - - for (int i = 0; i < 31; i++) - { - set_insert(set1, i); - } - - print_tree(set1->root, 0); - - set_free(set1, NULL); - - return 0; -} diff --git a/src/cmc/cmc/deque/code.h b/src/cmc/cmc/deque/code.h new file mode 100644 index 0000000..89ec618 --- /dev/null +++ b/src/cmc/cmc/deque/code.h @@ -0,0 +1,382 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* Implementation Detail Functions */ +/* None */ + +struct SNAME *CMC_(PFX, _new)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val) +{ + return CMC_(PFX, _new_custom)(capacity, f_val, NULL, NULL); +} + +struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, + struct CMC_ALLOC_NODE_NAME *alloc, struct CMC_CALLBACKS_NAME *callbacks) +{ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); + + if (capacity < 1) + return NULL; + + if (!f_val) + return NULL; + + if (!alloc) + alloc = &cmc_alloc_node_default; + + struct SNAME *_deque_ = alloc->malloc(sizeof(struct SNAME)); + + if (!_deque_) + return NULL; + + _deque_->buffer = alloc->calloc(capacity, sizeof(V)); + + if (!_deque_->buffer) + { + alloc->free(_deque_); + return NULL; + } + + _deque_->capacity = capacity; + _deque_->count = 0; + _deque_->front = 0; + _deque_->back = 0; + _deque_->flag = CMC_FLAG_OK; + _deque_->f_val = f_val; + _deque_->alloc = alloc; + CMC_CALLBACKS_ASSIGN(_deque_, callbacks); + + return _deque_; +} + +void CMC_(PFX, _clear)(struct SNAME *_deque_) +{ + if (_deque_->f_val->free) + { + for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) + { + _deque_->f_val->free(_deque_->buffer[i]); + + i = (i + 1) % _deque_->capacity; + } + } + + memset(_deque_->buffer, 0, sizeof(V) * _deque_->capacity); + + _deque_->count = 0; + _deque_->front = 0; + _deque_->back = 0; + + _deque_->flag = CMC_FLAG_OK; +} + +void CMC_(PFX, _free)(struct SNAME *_deque_) +{ + if (_deque_->f_val->free) + { + for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) + { + _deque_->f_val->free(_deque_->buffer[i]); + + i = (i + 1) % _deque_->capacity; + } + } + + _deque_->alloc->free(_deque_->buffer); + _deque_->alloc->free(_deque_); +} + +void CMC_(PFX, _customize)(struct SNAME *_deque_, struct CMC_ALLOC_NODE_NAME *alloc, + struct CMC_CALLBACKS_NAME *callbacks) +{ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); + + if (!alloc) + _deque_->alloc = &cmc_alloc_node_default; + else + _deque_->alloc = alloc; + + CMC_CALLBACKS_ASSIGN(_deque_, callbacks); + + _deque_->flag = CMC_FLAG_OK; +} + +bool CMC_(PFX, _push_front)(struct SNAME *_deque_, V value) +{ + if (CMC_(PFX, _full)(_deque_)) + { + if (!CMC_(PFX, _resize)(_deque_, _deque_->capacity * 2)) + return false; + } + + _deque_->front = (_deque_->front == 0) ? _deque_->capacity - 1 : _deque_->front - 1; + + _deque_->buffer[_deque_->front] = value; + + _deque_->count++; + _deque_->flag = CMC_FLAG_OK; + + CMC_CALLBACKS_CALL(_deque_, create); + + return true; +} + +bool CMC_(PFX, _push_back)(struct SNAME *_deque_, V value) +{ + if (CMC_(PFX, _full)(_deque_)) + { + if (!CMC_(PFX, _resize)(_deque_, _deque_->capacity * 2)) + return false; + } + + _deque_->buffer[_deque_->back] = value; + + _deque_->back = (_deque_->back == _deque_->capacity - 1) ? 0 : _deque_->back + 1; + + _deque_->count++; + _deque_->flag = CMC_FLAG_OK; + + CMC_CALLBACKS_CALL(_deque_, create); + + return true; +} + +bool CMC_(PFX, _pop_front)(struct SNAME *_deque_) +{ + if (CMC_(PFX, _empty)(_deque_)) + { + _deque_->flag = CMC_FLAG_EMPTY; + return false; + } + + _deque_->buffer[_deque_->front] = (V){ 0 }; + + _deque_->front = (_deque_->front == _deque_->capacity - 1) ? 0 : _deque_->front + 1; + + _deque_->count--; + _deque_->flag = CMC_FLAG_OK; + + CMC_CALLBACKS_CALL(_deque_, delete); + + return true; +} + +bool CMC_(PFX, _pop_back)(struct SNAME *_deque_) +{ + if (CMC_(PFX, _empty)(_deque_)) + { + _deque_->flag = CMC_FLAG_EMPTY; + return false; + } + + _deque_->back = (_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1; + + _deque_->buffer[_deque_->back] = (V){ 0 }; + + _deque_->count--; + _deque_->flag = CMC_FLAG_OK; + + CMC_CALLBACKS_CALL(_deque_, delete); + + return true; +} + +V CMC_(PFX, _front)(struct SNAME *_deque_) +{ + if (CMC_(PFX, _empty)(_deque_)) + { + _deque_->flag = CMC_FLAG_EMPTY; + return (V){ 0 }; + } + + _deque_->flag = CMC_FLAG_OK; + + CMC_CALLBACKS_CALL(_deque_, read); + + return _deque_->buffer[_deque_->front]; +} + +V CMC_(PFX, _back)(struct SNAME *_deque_) +{ + if (CMC_(PFX, _empty)(_deque_)) + { + _deque_->flag = CMC_FLAG_EMPTY; + return (V){ 0 }; + } + + _deque_->flag = CMC_FLAG_OK; + + CMC_CALLBACKS_CALL(_deque_, read); + + return _deque_->buffer[(_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1]; +} + +bool CMC_(PFX, _contains)(struct SNAME *_deque_, V value) +{ + _deque_->flag = CMC_FLAG_OK; + + bool result = false; + + for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) + { + if (_deque_->f_val->cmp(_deque_->buffer[i], value) == 0) + { + result = true; + break; + } + + i = (i + 1) % _deque_->capacity; + } + + CMC_CALLBACKS_CALL(_deque_, read); + + return result; +} + +bool CMC_(PFX, _empty)(struct SNAME *_deque_) +{ + return _deque_->count == 0; +} + +bool CMC_(PFX, _full)(struct SNAME *_deque_) +{ + return _deque_->count >= _deque_->capacity; +} + +size_t CMC_(PFX, _count)(struct SNAME *_deque_) +{ + return _deque_->count; +} + +size_t CMC_(PFX, _capacity)(struct SNAME *_deque_) +{ + return _deque_->capacity; +} + +int CMC_(PFX, _flag)(struct SNAME *_deque_) +{ + return _deque_->flag; +} + +bool CMC_(PFX, _resize)(struct SNAME *_deque_, size_t capacity) +{ + _deque_->flag = CMC_FLAG_OK; + + if (_deque_->capacity == capacity) + goto success; + + if (capacity < _deque_->count) + { + _deque_->flag = CMC_FLAG_INVALID; + return false; + } + + V *new_buffer = _deque_->alloc->malloc(sizeof(V) * capacity); + + if (!new_buffer) + { + _deque_->flag = CMC_FLAG_ALLOC; + return false; + } + + for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) + { + new_buffer[j] = _deque_->buffer[i]; + + i = (i + 1) % _deque_->capacity; + } + + _deque_->alloc->free(_deque_->buffer); + + _deque_->buffer = new_buffer; + _deque_->capacity = capacity; + _deque_->front = 0; + _deque_->back = _deque_->count; + +success: + + CMC_CALLBACKS_CALL(_deque_, resize); + + return true; +} + +struct SNAME *CMC_(PFX, _copy_of)(struct SNAME *_deque_) +{ + struct SNAME *result = CMC_(PFX, _new_custom)(_deque_->capacity, _deque_->f_val, _deque_->alloc, NULL); + + if (!result) + { + _deque_->flag = CMC_FLAG_ERROR; + return NULL; + } + + CMC_CALLBACKS_ASSIGN(result, _deque_->callbacks); + + if (_deque_->f_val->cpy) + { + for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) + { + result->buffer[j] = _deque_->f_val->cpy(_deque_->buffer[i]); + + i = (i + 1) % _deque_->capacity; + } + } + else + { + for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) + { + result->buffer[j] = _deque_->buffer[i]; + + i = (i + 1) % _deque_->capacity; + } + } + + result->count = _deque_->count; + result->front = 0; + result->back = _deque_->count; + + _deque_->flag = CMC_FLAG_OK; + + return result; +} + +bool CMC_(PFX, _equals)(struct SNAME *_deque1_, struct SNAME *_deque2_) +{ + _deque1_->flag = CMC_FLAG_OK; + _deque2_->flag = CMC_FLAG_OK; + + if (_deque1_->count != _deque2_->count) + return false; + + size_t i, j, k; + for (i = _deque1_->front, j = _deque2_->front, k = 0; k < _deque1_->count; k++) + { + if (_deque1_->f_val->cmp(_deque1_->buffer[i], _deque2_->buffer[j]) != 0) + return false; + + i = (i + 1) % _deque1_->capacity; + j = (j + 1) % _deque2_->capacity; + } + + return true; +} diff --git a/src/cmc/cmc/deque/ext/code.h b/src/cmc/cmc/deque/ext/code.h new file mode 100644 index 0000000..8e7f743 --- /dev/null +++ b/src/cmc/cmc/deque/ext/code.h @@ -0,0 +1,354 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * INIT + * + * The part 'INIT' gives a new way of initializing a collection. The collection + * struct is not heap allocated, only its internal structure (nodes, buffers). + */ +#ifdef CMC_EXT_DEQUE_INIT + +struct SNAME CMC_(PFX, _init)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val) +{ + return CMC_(PFX, _init_custom)(capacity, f_val, NULL, NULL); +} + +struct SNAME CMC_(PFX, _init_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, + struct CMC_ALLOC_NODE_NAME *alloc, struct CMC_CALLBACKS_NAME *callbacks) +{ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); + + struct SNAME _deque_ = { 0 }; + + if (capacity < 1) + return _deque_; + + if (!f_val) + return _deque_; + + if (!alloc) + alloc = &cmc_alloc_node_default; + + _deque_.buffer = alloc->calloc(capacity, sizeof(V)); + + if (!_deque_.buffer) + return _deque_; + + _deque_.capacity = capacity; + _deque_.count = 0; + _deque_.front = 0; + _deque_.back = 0; + _deque_.flag = CMC_FLAG_OK; + _deque_.f_val = f_val; + _deque_.alloc = alloc; + CMC_CALLBACKS_ASSIGN(&_deque_, callbacks); + + return _deque_; +} + +void CMC_(PFX, _release)(struct SNAME _deque_) +{ + if (_deque_.f_val->free) + { + for (size_t i = _deque_.front, j = 0; j < _deque_.count; j++) + { + _deque_.f_val->free(_deque_.buffer[i]); + + i = (i + 1) % _deque_.capacity; + } + } + + _deque_.alloc->free(_deque_.buffer); +} + +#endif /* CMC_EXT_DEQUE_INIT */ + +/** + * ITER + * + * Deque bi-directional iterator. + */ +#ifdef CMC_EXT_DEQUE_ITER + +struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME *target) +{ + struct CMC_DEF_ITER(SNAME) iter; + + iter.target = target; + iter.cursor = target->front; + iter.index = 0; + iter.start = true; + iter.end = CMC_(PFX, _empty)(target); + + return iter; +} + +struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME *target) +{ + struct CMC_DEF_ITER(SNAME) iter; + + iter.target = target; + + if (!CMC_(PFX, _empty)(target)) + { + if (iter.target->back == 0) + iter.cursor = iter.target->capacity - 1; + else + iter.cursor = iter.target->back - 1; + + iter.index = iter.target->count - 1; + } + else + { + iter.cursor = 0; + iter.index = 0; + } + + iter.start = CMC_(PFX, _empty)(target); + iter.end = true; + + return iter; +} + +bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) +{ + return CMC_(PFX, _empty)(iter->target) || iter->start; +} + +bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) +{ + return CMC_(PFX, _empty)(iter->target) || iter->end; +} + +bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) +{ + if (!CMC_(PFX, _empty)(iter->target)) + { + iter->cursor = iter->target->front; + iter->index = 0; + iter->start = true; + iter->end = false; + + return true; + } + + return false; +} + +bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) +{ + if (!CMC_(PFX, _empty)(iter->target)) + { + if (iter->target->back == 0) + iter->cursor = iter->target->capacity - 1; + else + iter->cursor = iter->target->back - 1; + + iter->index = iter->target->count - 1; + + iter->start = false; + iter->end = true; + + return true; + } + + return false; +} + +bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) +{ + if (iter->end) + return false; + + if (iter->index + 1 == iter->target->count) + { + iter->end = true; + return false; + } + + iter->start = CMC_(PFX, _empty)(iter->target); + + iter->cursor = (iter->cursor + 1) % (iter->target->capacity); + iter->index++; + + return true; +} + +bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) +{ + if (iter->start) + return false; + + if (iter->index == 0) + { + iter->start = true; + return false; + } + + iter->end = CMC_(PFX, _empty)(iter->target); + + iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1; + iter->index--; + + return true; +} + +/* Returns true only if the iterator moved */ +bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) +{ + if (iter->end) + return false; + + if (iter->index + 1 == iter->target->count) + { + iter->end = true; + return false; + } + + if (steps == 0 || iter->index + steps >= iter->target->count) + return false; + + iter->start = CMC_(PFX, _empty)(iter->target); + + iter->index += steps; + iter->cursor = (iter->cursor + steps) % iter->target->capacity; + + return true; +} + +/* Returns true only if the iterator moved */ +bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) +{ + if (iter->start) + return false; + + if (iter->index == 0) + { + iter->start = true; + return false; + } + + if (steps == 0 || iter->index < steps) + return false; + + iter->end = CMC_(PFX, _empty)(iter->target); + + iter->index -= steps; + + /* Prevent underflow */ + if (iter->cursor < steps) + iter->cursor += iter->target->capacity; + + iter->cursor -= steps; + + return true; +} + +/* Returns true only if the iterator was able to be positioned at the */ +/* given index */ +bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) +{ + if (index >= iter->target->count) + return false; + + if (iter->index > index) + return CMC_(PFX, _iter_rewind)(iter, iter->index - index); + else if (iter->index < index) + return CMC_(PFX, _iter_advance)(iter, index - iter->index); + + return true; +} + +V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) +{ + if (CMC_(PFX, _empty)(iter->target)) + return (V){ 0 }; + + return iter->target->buffer[iter->cursor]; +} + +V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) +{ + if (CMC_(PFX, _empty)(iter->target)) + return NULL; + + return &(iter->target->buffer[iter->cursor]); +} + +size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) +{ + return iter->index; +} + +#endif /* CMC_EXT_DEQUE_ITER */ + +/** + * STR + * + * Print helper functions. + */ +#ifdef CMC_EXT_DEQUE_STR + +bool CMC_(PFX, _to_string)(struct SNAME *_deque_, FILE *fptr) +{ + struct SNAME *d_ = _deque_; + + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" PRIuMAX ", " + "count:%" PRIuMAX ", " + "front:%" PRIuMAX ", " + "back:%" PRIuMAX ", " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + CMC_TO_STRING(SNAME), CMC_TO_STRING(V), d_, d_->buffer, d_->capacity, d_->count, d_->front, + d_->back, d_->flag, d_->f_val, d_->alloc, CMC_CALLBACKS_GET(d_)); +} + +bool CMC_(PFX, _print)(struct SNAME *_deque_, FILE *fptr, const char *start, const char *separator, const char *end) +{ + fprintf(fptr, "%s", start); + + for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) + { + if (!_deque_->f_val->str(fptr, _deque_->buffer[i])) + return false; + + i = (i + 1) % _deque_->capacity; + + if (j + 1 < _deque_->count) + fprintf(fptr, "%s", separator); + } + + fprintf(fptr, "%s", end); + + return true; +} + +#endif /* CMC_EXT_DEQUE_STR */ diff --git a/src/cmc/cmc/deque/ext/header.h b/src/cmc/cmc/deque/ext/header.h new file mode 100644 index 0000000..51cdea8 --- /dev/null +++ b/src/cmc/cmc/deque/ext/header.h @@ -0,0 +1,80 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * INIT + * + * The part 'INIT' gives a new way of initializing a collection. The collection + * struct is not heap allocated, only its internal structure (nodes, buffers). + */ +#ifdef CMC_EXT_DEQUE_INIT + +struct SNAME CMC_(PFX, _init)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val); +struct SNAME CMC_(PFX, _init_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, + struct CMC_ALLOC_NODE_NAME *alloc, struct CMC_CALLBACKS_NAME *callbacks); +void CMC_(PFX, _release)(struct SNAME _deque_); + +#endif /* CMC_EXT_DEQUE_INIT */ + +/** + * ITER + * + * Deque bi-directional iterator. + */ +#ifdef CMC_EXT_DEQUE_ITER + +/* Iterator Initialization */ +struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME *target); +struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME *target); +/* Iterator State */ +bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); +bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); +/* Iterator Movement */ +bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); +bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); +bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); +bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); +bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); +bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); +bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); +/* Iterator Access */ +V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); +V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); +size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); + +#endif /* CMC_EXT_DEQUE_ITER */ + +/** + * STR + * + * Print helper functions. + */ +#ifdef CMC_EXT_DEQUE_STR + +/* Debug prints the struct to fptr */ +bool CMC_(PFX, _to_string)(struct SNAME *_deque_, FILE *fptr); +/* Prints each item in the deque as an array */ +bool CMC_(PFX, _print)(struct SNAME *_deque_, FILE *fptr, const char *start, const char *separator, const char *end); + +#endif /* CMC_EXT_DEQUE_STR */ diff --git a/src/cmc/cmc/deque/ext/struct.h b/src/cmc/cmc/deque/ext/struct.h new file mode 100644 index 0000000..4be767d --- /dev/null +++ b/src/cmc/cmc/deque/ext/struct.h @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * ITER + * + * Deque bi-directional iterator. + */ +#ifdef CMC_EXT_DEQUE_ITER + +/* Deque Iterator */ +struct CMC_DEF_ITER(SNAME) +{ + /* Target deque */ + struct SNAME *target; + /* Cursor's position (index) */ + size_t cursor; + /* Keeps track of relative index to the iteration of elements */ + size_t index; + /* If the iterator has reached the start of the iteration */ + bool start; + /* If the iterator has reached the end of the iteration */ + bool end; +}; + +#endif /* CMC_EXT_DEQUE_ITER */ diff --git a/src/cmc/cmc/deque/header.h b/src/cmc/cmc/deque/header.h new file mode 100644 index 0000000..54576fb --- /dev/null +++ b/src/cmc/cmc/deque/header.h @@ -0,0 +1,52 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* Collection Allocation and Deallocation */ +struct SNAME *CMC_(PFX, _new)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val); +struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, + struct CMC_ALLOC_NODE_NAME *alloc, struct CMC_CALLBACKS_NAME *callbacks); +void CMC_(PFX, _clear)(struct SNAME *_deque_); +void CMC_(PFX, _free)(struct SNAME *_deque_); +/* Customization of Allocation and Callbacks */ +void CMC_(PFX, _customize)(struct SNAME *_deque_, struct CMC_ALLOC_NODE_NAME *alloc, + struct CMC_CALLBACKS_NAME *callbacks); +/* Collection Input and Output */ +bool CMC_(PFX, _push_front)(struct SNAME *_deque_, V value); +bool CMC_(PFX, _push_back)(struct SNAME *_deque_, V value); +bool CMC_(PFX, _pop_front)(struct SNAME *_deque_); +bool CMC_(PFX, _pop_back)(struct SNAME *_deque_); +/* Element Access */ +V CMC_(PFX, _front)(struct SNAME *_deque_); +V CMC_(PFX, _back)(struct SNAME *_deque_); +/* Collection State */ +bool CMC_(PFX, _contains)(struct SNAME *_deque_, V value); +bool CMC_(PFX, _empty)(struct SNAME *_deque_); +bool CMC_(PFX, _full)(struct SNAME *_deque_); +size_t CMC_(PFX, _count)(struct SNAME *_deque_); +size_t CMC_(PFX, _capacity)(struct SNAME *_deque_); +int CMC_(PFX, _flag)(struct SNAME *_deque_); +/* Collection Utility */ +bool CMC_(PFX, _resize)(struct SNAME *_deque_, size_t capacity); +struct SNAME *CMC_(PFX, _copy_of)(struct SNAME *_deque_); +bool CMC_(PFX, _equals)(struct SNAME *_deque1_, struct SNAME *_deque2_); diff --git a/src/cmc/cmc/deque/struct.h b/src/cmc/cmc/deque/struct.h new file mode 100644 index 0000000..69ae077 --- /dev/null +++ b/src/cmc/cmc/deque/struct.h @@ -0,0 +1,61 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +struct SNAME +{ + /* Dynamic circular array of elements */ + V *buffer; + /* Current circular array capacity */ + size_t capacity; + /* Current amount of elements */ + size_t count; + /* Index representing the front of the deque */ + size_t front; + /* Index representing the back of the deque */ + size_t back; + /* Flags indicating errors or success */ + int flag; + /* Functions Table */ + struct CMC_DEF_FVAL(SNAME) * f_val; + /* Custom allocation functions */ + struct CMC_ALLOC_NODE_NAME *alloc; + /* Custom callback functions */ + CMC_CALLBACKS_DECL; +}; + +struct CMC_DEF_FVAL(SNAME) +{ + /* Comparator function */ + CMC_DEF_FTAB_CMP(V); + /* Copy function */ + CMC_DEF_FTAB_CPY(V); + /* To string function */ + CMC_DEF_FTAB_STR(V); + /* Free from memory function */ + CMC_DEF_FTAB_FREE(V); + /* Hash function */ + CMC_DEF_FTAB_HASH(V); + /* Priority function */ + CMC_DEF_FTAB_PRI(V); +}; diff --git a/src/cmc/cmc/list/code.h b/src/cmc/cmc/list/code.h new file mode 100644 index 0000000..0de9edd --- /dev/null +++ b/src/cmc/cmc/list/code.h @@ -0,0 +1,459 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* Implementation Detail Functions */ +/* None */ + +struct SNAME *CMC_(PFX, _new)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val) +{ + return CMC_(PFX, _new_custom)(capacity, f_val, NULL, NULL); +} + +struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, + struct CMC_ALLOC_NODE_NAME *alloc, struct CMC_CALLBACKS_NAME *callbacks) +{ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); + + if (capacity < 1) + return NULL; + + if (!f_val) + return NULL; + + if (!alloc) + alloc = &cmc_alloc_node_default; + + struct SNAME *_list_ = alloc->malloc(sizeof(struct SNAME)); + + if (!_list_) + return NULL; + + _list_->buffer = alloc->calloc(capacity, sizeof(V)); + + if (!_list_->buffer) + { + alloc->free(_list_); + return NULL; + } + + _list_->capacity = capacity; + _list_->count = 0; + _list_->flag = CMC_FLAG_OK; + _list_->f_val = f_val; + _list_->alloc = alloc; + CMC_CALLBACKS_ASSIGN(_list_, callbacks); + + return _list_; +} + +void CMC_(PFX, _clear)(struct SNAME *_list_) +{ + if (_list_->f_val->free) + { + for (size_t i = 0; i < _list_->count; i++) + _list_->f_val->free(_list_->buffer[i]); + } + + memset(_list_->buffer, 0, sizeof(V) * _list_->capacity); + + _list_->count = 0; + _list_->flag = CMC_FLAG_OK; +} + +void CMC_(PFX, _free)(struct SNAME *_list_) +{ + if (_list_->f_val->free) + { + for (size_t i = 0; i < _list_->count; i++) + _list_->f_val->free(_list_->buffer[i]); + } + + _list_->alloc->free(_list_->buffer); + _list_->alloc->free(_list_); +} + +void CMC_(PFX, _customize)(struct SNAME *_list_, struct CMC_ALLOC_NODE_NAME *alloc, + struct CMC_CALLBACKS_NAME *callbacks) +{ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); + + if (!alloc) + _list_->alloc = &cmc_alloc_node_default; + else + _list_->alloc = alloc; + + CMC_CALLBACKS_ASSIGN(_list_, callbacks); + + _list_->flag = CMC_FLAG_OK; +} + +bool CMC_(PFX, _push_front)(struct SNAME *_list_, V value) +{ + if (CMC_(PFX, _full)(_list_)) + { + if (!CMC_(PFX, _resize)(_list_, _list_->count * 2)) + return false; + } + + if (!CMC_(PFX, _empty)(_list_)) + { + memmove(_list_->buffer + 1, _list_->buffer, _list_->count * sizeof(V)); + } + + _list_->buffer[0] = value; + + _list_->count++; + _list_->flag = CMC_FLAG_OK; + + CMC_CALLBACKS_CALL(_list_, create); + + return true; +} + +bool CMC_(PFX, _push_at)(struct SNAME *_list_, V value, size_t index) +{ + if (index > _list_->count) + { + _list_->flag = CMC_FLAG_RANGE; + return false; + } + + if (CMC_(PFX, _full)(_list_)) + { + if (!CMC_(PFX, _resize)(_list_, _list_->count * 2)) + return false; + } + + memmove(_list_->buffer + index + 1, _list_->buffer + index, (_list_->count - index) * sizeof(V)); + + _list_->buffer[index] = value; + _list_->count++; + _list_->flag = CMC_FLAG_OK; + + CMC_CALLBACKS_CALL(_list_, create); + + return true; +} + +bool CMC_(PFX, _push_back)(struct SNAME *_list_, V value) +{ + if (CMC_(PFX, _full)(_list_)) + { + if (!CMC_(PFX, _resize)(_list_, _list_->count * 2)) + return false; + } + + _list_->buffer[_list_->count++] = value; + _list_->flag = CMC_FLAG_OK; + + CMC_CALLBACKS_CALL(_list_, create); + + return true; +} + +bool CMC_(PFX, _pop_front)(struct SNAME *_list_) +{ + if (CMC_(PFX, _empty)(_list_)) + { + _list_->flag = CMC_FLAG_EMPTY; + return false; + } + + memmove(_list_->buffer, _list_->buffer + 1, (_list_->count - 1) * sizeof(V)); + + _list_->buffer[--_list_->count] = (V){ 0 }; + _list_->flag = CMC_FLAG_OK; + + CMC_CALLBACKS_CALL(_list_, delete); + + return true; +} + +bool CMC_(PFX, _pop_at)(struct SNAME *_list_, size_t index) +{ + if (CMC_(PFX, _empty)(_list_)) + { + _list_->flag = CMC_FLAG_EMPTY; + return false; + } + + if (index >= _list_->count) + { + _list_->flag = CMC_FLAG_RANGE; + return false; + } + + memmove(_list_->buffer + index, _list_->buffer + index + 1, (_list_->count - index - 1) * sizeof(V)); + + _list_->buffer[--_list_->count] = (V){ 0 }; + _list_->flag = CMC_FLAG_OK; + + CMC_CALLBACKS_CALL(_list_, delete); + + return true; +} + +bool CMC_(PFX, _pop_back)(struct SNAME *_list_) +{ + if (CMC_(PFX, _empty)(_list_)) + return false; + + _list_->buffer[--_list_->count] = (V){ 0 }; + _list_->flag = CMC_FLAG_OK; + + CMC_CALLBACKS_CALL(_list_, delete); + + return true; +} + +V CMC_(PFX, _front)(struct SNAME *_list_) +{ + if (CMC_(PFX, _empty)(_list_)) + { + _list_->flag = CMC_FLAG_EMPTY; + return (V){ 0 }; + } + + _list_->flag = CMC_FLAG_OK; + + CMC_CALLBACKS_CALL(_list_, read); + + return _list_->buffer[0]; +} + +V CMC_(PFX, _get)(struct SNAME *_list_, size_t index) +{ + if (CMC_(PFX, _empty)(_list_)) + { + _list_->flag = CMC_FLAG_EMPTY; + return (V){ 0 }; + } + + if (index >= _list_->count) + { + _list_->flag = CMC_FLAG_RANGE; + return (V){ 0 }; + } + + _list_->flag = CMC_FLAG_OK; + + CMC_CALLBACKS_CALL(_list_, read); + + return _list_->buffer[index]; +} + +V *CMC_(PFX, _get_ref)(struct SNAME *_list_, size_t index) +{ + if (CMC_(PFX, _empty)(_list_)) + { + _list_->flag = CMC_FLAG_EMPTY; + return NULL; + } + + if (index >= _list_->count) + { + _list_->flag = CMC_FLAG_RANGE; + return NULL; + } + + _list_->flag = CMC_FLAG_OK; + + CMC_CALLBACKS_CALL(_list_, read); + + return &(_list_->buffer[index]); +} + +V CMC_(PFX, _back)(struct SNAME *_list_) +{ + if (CMC_(PFX, _empty)(_list_)) + { + _list_->flag = CMC_FLAG_EMPTY; + return (V){ 0 }; + } + + _list_->flag = CMC_FLAG_OK; + + CMC_CALLBACKS_CALL(_list_, read); + + return _list_->buffer[_list_->count - 1]; +} + +size_t CMC_(PFX, _index_of)(struct SNAME *_list_, V value, bool from_start) +{ + _list_->flag = CMC_FLAG_OK; + + size_t result = _list_->count; + + if (from_start) + { + for (size_t i = 0; i < _list_->count; i++) + { + if (_list_->f_val->cmp(_list_->buffer[i], value) == 0) + { + result = i; + break; + } + } + } + else + { + for (size_t i = _list_->count; i > 0; i--) + { + if (_list_->f_val->cmp(_list_->buffer[i - 1], value) == 0) + { + result = i - 1; + break; + } + } + } + + CMC_CALLBACKS_CALL(_list_, read); + + return result; +} + +bool CMC_(PFX, _contains)(struct SNAME *_list_, V value) +{ + _list_->flag = CMC_FLAG_OK; + + bool result = false; + + for (size_t i = 0; i < _list_->count; i++) + { + if (_list_->f_val->cmp(_list_->buffer[i], value) == 0) + { + result = true; + break; + } + } + + CMC_CALLBACKS_CALL(_list_, read); + + return result; +} + +bool CMC_(PFX, _empty)(struct SNAME *_list_) +{ + return _list_->count == 0; +} + +bool CMC_(PFX, _full)(struct SNAME *_list_) +{ + return _list_->count >= _list_->capacity; +} + +size_t CMC_(PFX, _count)(struct SNAME *_list_) +{ + return _list_->count; +} + +bool CMC_(PFX, _fits)(struct SNAME *_list_, size_t size) +{ + return _list_->count + size <= _list_->capacity; +} + +size_t CMC_(PFX, _capacity)(struct SNAME *_list_) +{ + return _list_->capacity; +} + +int CMC_(PFX, _flag)(struct SNAME *_list_) +{ + return _list_->flag; +} + +bool CMC_(PFX, _resize)(struct SNAME *_list_, size_t capacity) +{ + _list_->flag = CMC_FLAG_OK; + + if (_list_->capacity == capacity) + return true; + + if (capacity < _list_->count) + { + _list_->flag = CMC_FLAG_INVALID; + return false; + } + + V *new_buffer = _list_->alloc->realloc(_list_->buffer, sizeof(V) * capacity); + + if (!new_buffer) + { + _list_->flag = CMC_FLAG_ALLOC; + return false; + } + + /* TODO zero out new slots */ + + _list_->buffer = new_buffer; + _list_->capacity = capacity; + + CMC_CALLBACKS_CALL(_list_, resize); + + return true; +} + +struct SNAME *CMC_(PFX, _copy_of)(struct SNAME *_list_) +{ + struct SNAME *result = CMC_(PFX, _new_custom)(_list_->capacity, _list_->f_val, _list_->alloc, NULL); + + if (!result) + { + _list_->flag = CMC_FLAG_ALLOC; + return NULL; + } + + CMC_CALLBACKS_ASSIGN(result, _list_->callbacks); + + if (_list_->f_val->cpy) + { + for (size_t i = 0; i < _list_->count; i++) + result->buffer[i] = _list_->f_val->cpy(_list_->buffer[i]); + } + else + memcpy(result->buffer, _list_->buffer, sizeof(V) * _list_->count); + + result->count = _list_->count; + + _list_->flag = CMC_FLAG_OK; + + return result; +} + +bool CMC_(PFX, _equals)(struct SNAME *_list1_, struct SNAME *_list2_) +{ + _list1_->flag = CMC_FLAG_OK; + _list2_->flag = CMC_FLAG_OK; + + if (_list1_->count != _list2_->count) + return false; + + for (size_t i = 0; i < _list1_->count; i++) + { + if (0 != _list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i])) + return false; + } + + return true; +} diff --git a/src/cmc/cmc/list/ext/code.h b/src/cmc/cmc/list/ext/code.h new file mode 100644 index 0000000..97e39a8 --- /dev/null +++ b/src/cmc/cmc/list/ext/code.h @@ -0,0 +1,479 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * INIT + * + * The part 'INIT' gives a new way of initializing a collection. The collection + * struct is not heap allocated, only its internal structure (nodes, buffers). + */ +#ifdef CMC_EXT_LIST_INIT + +struct SNAME CMC_(PFX, _init)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val) +{ + return CMC_(PFX, _init_custom)(capacity, f_val, NULL, NULL); +} + +struct SNAME CMC_(PFX, _init_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, + struct CMC_ALLOC_NODE_NAME *alloc, struct CMC_CALLBACKS_NAME *callbacks) +{ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); + + struct SNAME _list_ = { 0 }; + + if (capacity < 1) + return _list_; + + if (!f_val) + return _list_; + + if (!alloc) + alloc = &cmc_alloc_node_default; + + _list_.buffer = alloc->calloc(capacity, sizeof(V)); + + if (!_list_.buffer) + return _list_; + + _list_.capacity = capacity; + _list_.count = 0; + _list_.flag = CMC_FLAG_OK; + _list_.f_val = f_val; + _list_.alloc = alloc; + CMC_CALLBACKS_ASSIGN(&_list_, callbacks); + + return _list_; +} + +void CMC_(PFX, _release)(struct SNAME _list_) +{ + if (_list_.f_val->free) + { + for (size_t i = 0; i < _list_.count; i++) + _list_.f_val->free(_list_.buffer[i]); + } + + _list_.alloc->free(_list_.buffer); +} + +#endif /* CMC_EXT_LIST_INIT */ + +/** + * ITER + * + * List bi-directional iterator. + */ +#ifdef CMC_EXT_LIST_ITER + +struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME *target) +{ + struct CMC_DEF_ITER(SNAME) iter; + + iter.target = target; + iter.cursor = 0; + iter.start = true; + iter.end = CMC_(PFX, _empty)(target); + + return iter; +} + +struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME *target) +{ + struct CMC_DEF_ITER(SNAME) iter; + + iter.target = target; + iter.cursor = 0; + iter.start = CMC_(PFX, _empty)(target); + iter.end = true; + + if (!CMC_(PFX, _empty)(target)) + iter.cursor = target->count - 1; + + return iter; +} + +bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) +{ + return CMC_(PFX, _empty)(iter->target) || iter->start; +} + +bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) +{ + return CMC_(PFX, _empty)(iter->target) || iter->end; +} + +bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) +{ + if (!CMC_(PFX, _empty)(iter->target)) + { + iter->cursor = 0; + iter->start = true; + iter->end = CMC_(PFX, _empty)(iter->target); + + return true; + } + + return false; +} + +bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) +{ + if (!CMC_(PFX, _empty)(iter->target)) + { + iter->start = CMC_(PFX, _empty)(iter->target); + iter->cursor = iter->target->count - 1; + iter->end = true; + + return true; + } + + return false; +} + +bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) +{ + if (iter->end) + return false; + + if (iter->cursor + 1 == iter->target->count) + { + iter->end = true; + return false; + } + + iter->start = CMC_(PFX, _empty)(iter->target); + + iter->cursor++; + + return true; +} + +bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) +{ + if (iter->start) + return false; + + if (iter->cursor == 0) + { + iter->start = true; + return false; + } + + iter->end = CMC_(PFX, _empty)(iter->target); + + iter->cursor--; + + return true; +} + +/* Returns true only if the iterator moved */ +bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) +{ + if (iter->end) + return false; + + if (iter->cursor + 1 == iter->target->count) + { + iter->end = true; + return false; + } + + if (steps == 0 || iter->cursor + steps >= iter->target->count) + return false; + + iter->start = CMC_(PFX, _empty)(iter->target); + + iter->cursor += steps; + + return true; +} + +/* Returns true only if the iterator moved */ +bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) +{ + if (iter->start) + return false; + + if (iter->cursor == 0) + { + iter->start = true; + return false; + } + + if (steps == 0 || iter->cursor < steps) + return false; + + iter->end = CMC_(PFX, _empty)(iter->target); + + iter->cursor -= steps; + + return true; +} + +/* Returns true only if the iterator was able to be positioned at the */ +/* given index */ +bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) +{ + if (index >= iter->target->count) + return false; + + if (iter->cursor > index) + return CMC_(PFX, _iter_rewind)(iter, iter->cursor - index); + else if (iter->cursor < index) + return CMC_(PFX, _iter_advance)(iter, index - iter->cursor); + + return true; +} + +V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) +{ + if (CMC_(PFX, _empty)(iter->target)) + return (V){ 0 }; + + return iter->target->buffer[iter->cursor]; +} + +V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) +{ + if (CMC_(PFX, _empty)(iter->target)) + return NULL; + + return &(iter->target->buffer[iter->cursor]); +} + +size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) +{ + return iter->cursor; +} + +#endif /* CMC_EXT_LIST_ITER */ + +/** + * SEQ + * + * Push and pop sequence of items. + */ +#ifdef CMC_EXT_LIST_SEQ + +bool CMC_(PFX, _seq_push_front)(struct SNAME *_list_, V *values, size_t size) +{ + if (size == 0) + { + _list_->flag = CMC_FLAG_INVALID; + return false; + } + + if (!CMC_(PFX, _fits)(_list_, size)) + { + if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) + return false; + } + + memmove(_list_->buffer + size, _list_->buffer, _list_->count * sizeof(V)); + + memcpy(_list_->buffer, values, size * sizeof(V)); + + _list_->count += size; + _list_->flag = CMC_FLAG_OK; + + CMC_CALLBACKS_CALL(_list_, create); + + return true; +} + +bool CMC_(PFX, _seq_push_at)(struct SNAME *_list_, V *values, size_t size, size_t index) +{ + if (size == 0) + { + _list_->flag = CMC_FLAG_INVALID; + return false; + } + + if (index > _list_->count) + { + _list_->flag = CMC_FLAG_RANGE; + return false; + } + + if (index == 0) + return CMC_(PFX, _seq_push_front)(_list_, values, size); + else if (index == _list_->count) + return CMC_(PFX, _seq_push_back)(_list_, values, size); + + if (!CMC_(PFX, _fits)(_list_, size)) + { + if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) + return false; + } + + memmove(_list_->buffer + index + size, _list_->buffer + index, (_list_->count - index) * sizeof(V)); + + memcpy(_list_->buffer + index, values, size * sizeof(V)); + + _list_->count += size; + _list_->flag = CMC_FLAG_OK; + + CMC_CALLBACKS_CALL(_list_, create); + + return true; +} + +bool CMC_(PFX, _seq_push_back)(struct SNAME *_list_, V *values, size_t size) +{ + if (size == 0) + { + _list_->flag = CMC_FLAG_INVALID; + return false; + } + + if (!CMC_(PFX, _fits)(_list_, size)) + { + if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) + return false; + } + + memcpy(_list_->buffer + _list_->count, values, size * sizeof(V)); + + _list_->count += size; + _list_->flag = CMC_FLAG_OK; + + CMC_CALLBACKS_CALL(_list_, create); + + return true; +} + +bool CMC_(PFX, _seq_pop_at)(struct SNAME *_list_, size_t from, size_t to) +{ + if (from > to) + { + _list_->flag = CMC_FLAG_INVALID; + return false; + } + + if (to >= _list_->count) + { + _list_->flag = CMC_FLAG_RANGE; + return false; + } + + size_t length = (to - from + 1); + + memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(V)); + + memset(_list_->buffer + _list_->count - length, 0, length * sizeof(V)); + + _list_->count -= to - from + 1; + _list_->flag = CMC_FLAG_OK; + + CMC_CALLBACKS_CALL(_list_, delete); + + return true; +} + +struct SNAME *CMC_(PFX, _seq_sublist)(struct SNAME *_list_, size_t from, size_t to) +{ + if (from > to) + { + _list_->flag = CMC_FLAG_INVALID; + return NULL; + } + + if (to >= _list_->count) + { + _list_->flag = CMC_FLAG_RANGE; + return NULL; + } + + size_t length = to - from + 1; + + struct SNAME *result = CMC_(PFX, _new_custom)(length, _list_->f_val, _list_->alloc, CMC_CALLBACKS_GET(_list_)); + + if (!result) + { + _list_->flag = CMC_FLAG_ALLOC; + return NULL; + } + + memcpy(result->buffer, _list_->buffer, length * sizeof(V)); + + memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(V)); + + memset(_list_->buffer + _list_->count - length, 0, length * sizeof(V)); + + _list_->count -= length; + result->count = length; + + _list_->flag = CMC_FLAG_OK; + + CMC_CALLBACKS_CALL(_list_, delete); + + return result; +} + +#endif /* CMC_EXT_LIST_SEQ */ + +/** + * STR + * + * Print helper functions. + */ +#ifdef CMC_EXT_LIST_STR + +bool CMC_(PFX, _to_string)(struct SNAME *_list_, FILE *fptr) +{ + struct SNAME *l_ = _list_; + + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" PRIuMAX ", " + "count:%" PRIuMAX ", " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + CMC_TO_STRING(SNAME), CMC_TO_STRING(V), l_, l_->buffer, l_->capacity, l_->count, l_->flag, + l_->f_val, l_->alloc, CMC_CALLBACKS_GET(l_)); +} + +bool CMC_(PFX, _print)(struct SNAME *_list_, FILE *fptr, const char *start, const char *separator, const char *end) +{ + fprintf(fptr, "%s", start); + + for (size_t i = 0; i < _list_->count; i++) + { + if (!_list_->f_val->str(fptr, _list_->buffer[i])) + return false; + + if (i + 1 < _list_->count) + fprintf(fptr, "%s", separator); + } + + fprintf(fptr, "%s", end); + + return true; +} + +#endif /* CMC_EXT_LIST_STR */ diff --git a/src/cmc/cmc/list/ext/header.h b/src/cmc/cmc/list/ext/header.h new file mode 100644 index 0000000..67deb82 --- /dev/null +++ b/src/cmc/cmc/list/ext/header.h @@ -0,0 +1,96 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * INIT + * + * The part 'INIT' gives a new way of initializing a collection. The collection + * struct is not heap allocated, only its internal structure (nodes, buffers). + */ +#ifdef CMC_EXT_LIST_INIT + +struct SNAME CMC_(PFX, _init)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val); +struct SNAME CMC_(PFX, _init_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, + struct CMC_ALLOC_NODE_NAME *alloc, struct CMC_CALLBACKS_NAME *callbacks); +void CMC_(PFX, _release)(struct SNAME _list_); + +#endif /* CMC_EXT_LIST_INIT */ + +/** + * ITER + * + * List bi-directional iterator. + */ +#ifdef CMC_EXT_LIST_ITER + +/* Iterator Initialization */ +struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME *target); +struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME *target); +/* Iterator State */ +bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); +bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); +/* Iterator Movement */ +bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); +bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); +bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); +bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); +bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); +bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); +bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); +/* Iterator Access */ +V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); +V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); +size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); + +#endif /* CMC_EXT_LIST_ITER */ + +/** + * SEQ + * + * Push and pop sequence of items. + */ +#ifdef CMC_EXT_LIST_SEQ + +/* List Sequence Input and Output */ +bool CMC_(PFX, _seq_push_front)(struct SNAME *_list_, V *values, size_t size); +bool CMC_(PFX, _seq_push_at)(struct SNAME *_list_, V *values, size_t size, size_t index); +bool CMC_(PFX, _seq_push_back)(struct SNAME *_list_, V *values, size_t size); +bool CMC_(PFX, _seq_pop_at)(struct SNAME *_list_, size_t from, size_t to); +struct SNAME *CMC_(PFX, _seq_sublist)(struct SNAME *_list_, size_t from, size_t to); + +#endif /* CMC_EXT_LIST_SEQ */ + +/** + * STR + * + * Print helper functions. + */ +#ifdef CMC_EXT_LIST_STR + +/* Debug prints the struct to fptr */ +bool CMC_(PFX, _to_string)(struct SNAME *_list_, FILE *fptr); +/* Prints each item in the list as an array */ +bool CMC_(PFX, _print)(struct SNAME *_list_, FILE *fptr, const char *start, const char *separator, const char *end); + +#endif /* CMC_EXT_LIST_STR */ diff --git a/src/ext_cmc_bitset.h b/src/cmc/cmc/list/ext/struct.h similarity index 62% rename from src/ext_cmc_bitset.h rename to src/cmc/cmc/list/ext/struct.h index 3e431a4..88eba84 100644 --- a/src/ext_cmc_bitset.h +++ b/src/cmc/cmc/list/ext/struct.h @@ -23,34 +23,26 @@ */ /** - * ext_cmc_bitset.h - * - * Creation Date: 08/06/2020 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) + * ITER * + * List bi-directional iterator. */ +#ifdef CMC_EXT_DEQUE_ITER -#ifndef CMC_EXT_CMC_BITSET_H -#define CMC_EXT_CMC_BITSET_H +/* List Iterator */ +struct CMC_DEF_ITER(SNAME) +{ + /* Target List */ + struct SNAME *target; -#include "cor_core.h" + /* Cursor's position (index) */ + size_t cursor; -/** - * All the EXT parts of CMC BitSet. - */ -#define CMC_EXT_CMC_BITSET_PARTS PLACEHOLDER + /* If the iterator has reached the start of the iteration */ + bool start; -#define CMC_EXT_CMC_BITSET_PLACEHOLDER(ACCESS, FILE, PARAMS) \ - CMC_(CMC_(CMC_EXT_CMC_BITSET_PLACEHOLDER_, ACCESS), CMC_(_, FILE))(PARAMS) + /* If the iterator has reached the end of the iteration */ + bool end; +}; -#define CMC_EXT_CMC_BITSET_PLACEHOLDER_PUBLIC_HEADER(PARAMS) - -#define CMC_EXT_CMC_BITSET_PLACEHOLDER_PUBLIC_SOURCE(PARAMS) - -#define CMC_EXT_CMC_BITSET_PLACEHOLDER_PRIVATE_HEADER(PARAMS) - -#define CMC_EXT_CMC_BITSET_PLACEHOLDER_PRIVATE_SOURCE(PARAMS) - -#endif /* CMC_EXT_CMC_BITSET_H */ +#endif /* CMC_EXT_DEQUE_ITER */ diff --git a/src/cmc/cmc/list/header.h b/src/cmc/cmc/list/header.h new file mode 100644 index 0000000..c15ed66 --- /dev/null +++ b/src/cmc/cmc/list/header.h @@ -0,0 +1,58 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* Collection Allocation and Deallocation */ +struct SNAME *CMC_(PFX, _new)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val); +struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, + struct CMC_ALLOC_NODE_NAME *alloc, struct CMC_CALLBACKS_NAME *callbacks); +void CMC_(PFX, _clear)(struct SNAME *_list_); +void CMC_(PFX, _free)(struct SNAME *_list_); +/* Customization of Allocation and Callbacks */ +void CMC_(PFX, _customize)(struct SNAME *_list_, struct CMC_ALLOC_NODE_NAME *alloc, + struct CMC_CALLBACKS_NAME *callbacks); +/* Collection Input and Output */ +bool CMC_(PFX, _push_front)(struct SNAME *_list_, V value); +bool CMC_(PFX, _push_at)(struct SNAME *_list_, V value, size_t index); +bool CMC_(PFX, _push_back)(struct SNAME *_list_, V value); +bool CMC_(PFX, _pop_front)(struct SNAME *_list_); +bool CMC_(PFX, _pop_at)(struct SNAME *_list_, size_t index); +bool CMC_(PFX, _pop_back)(struct SNAME *_list_); +/* Element Access */ +V CMC_(PFX, _front)(struct SNAME *_list_); +V CMC_(PFX, _get)(struct SNAME *_list_, size_t index); +V *CMC_(PFX, _get_ref)(struct SNAME *_list_, size_t index); +V CMC_(PFX, _back)(struct SNAME *_list_); +size_t CMC_(PFX, _index_of)(struct SNAME *_list_, V value, bool from_start); +/* Collection State */ +bool CMC_(PFX, _contains)(struct SNAME *_list_, V value); +bool CMC_(PFX, _empty)(struct SNAME *_list_); +bool CMC_(PFX, _full)(struct SNAME *_list_); +size_t CMC_(PFX, _count)(struct SNAME *_list_); +bool CMC_(PFX, _fits)(struct SNAME *_list_, size_t size); +size_t CMC_(PFX, _capacity)(struct SNAME *_list_); +int CMC_(PFX, _flag)(struct SNAME *_list_); +/* Collection Utility */ +bool CMC_(PFX, _resize)(struct SNAME *_list_, size_t capacity); +struct SNAME *CMC_(PFX, _copy_of)(struct SNAME *_list_); +bool CMC_(PFX, _equals)(struct SNAME *_list1_, struct SNAME *_list2_); diff --git a/src/cmc/cmc/list/struct.h b/src/cmc/cmc/list/struct.h new file mode 100644 index 0000000..e0b563c --- /dev/null +++ b/src/cmc/cmc/list/struct.h @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +struct SNAME +{ + /* Dynamic array of elements */ + V *buffer; + /* Current array capacity */ + size_t capacity; + /* Current amount of elements */ + size_t count; + /* Flags indicating errors or success */ + int flag; + /* Value function table */ + struct CMC_DEF_FVAL(SNAME) * f_val; + /* Custom allocation functions */ + struct CMC_ALLOC_NODE_NAME *alloc; + /* Custom callback functions */ + CMC_CALLBACKS_DECL; +}; + +struct CMC_DEF_FVAL(SNAME) +{ + /* Comparator function */ + CMC_DEF_FTAB_CMP(V); + /* Copy function */ + CMC_DEF_FTAB_CPY(V); + /* To string function */ + CMC_DEF_FTAB_STR(V); + /* Free from memory function */ + CMC_DEF_FTAB_FREE(V); + /* Hash function */ + CMC_DEF_FTAB_HASH(V); + /* Priority function */ + CMC_DEF_FTAB_PRI(V); +}; diff --git a/src/cmc/cmc/stack/code.h b/src/cmc/cmc/stack/code.h new file mode 100644 index 0000000..f34ed6d --- /dev/null +++ b/src/cmc/cmc/stack/code.h @@ -0,0 +1,279 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* Implementation Detail Functions */ +/* None */ + +struct SNAME *CMC_(PFX, _new)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val) +{ + return CMC_(PFX, _new_custom)(capacity, f_val, NULL, NULL); +} + +struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, + struct CMC_ALLOC_NODE_NAME *alloc, struct CMC_CALLBACKS_NAME *callbacks) +{ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); + + if (capacity < 1) + return NULL; + if (!f_val) + return NULL; + + if (!alloc) + alloc = &cmc_alloc_node_default; + + struct SNAME *_stack_ = alloc->malloc(sizeof(struct SNAME)); + + if (!_stack_) + return NULL; + + _stack_->buffer = alloc->calloc(capacity, sizeof(V)); + + if (!_stack_->buffer) + { + alloc->free(_stack_); + return NULL; + } + + _stack_->capacity = capacity; + _stack_->count = 0; + _stack_->flag = CMC_FLAG_OK; + _stack_->f_val = f_val; + _stack_->alloc = alloc; + CMC_CALLBACKS_ASSIGN(_stack_, callbacks); + + return _stack_; +} + +void CMC_(PFX, _clear)(struct SNAME *_stack_) +{ + if (_stack_->f_val->free) + { + for (size_t i = 0; i < _stack_->count; i++) + _stack_->f_val->free(_stack_->buffer[i]); + } + + memset(_stack_->buffer, 0, sizeof(V) * _stack_->capacity); + + _stack_->count = 0; + _stack_->flag = CMC_FLAG_OK; +} + +void CMC_(PFX, _free)(struct SNAME *_stack_) +{ + if (_stack_->f_val->free) + { + for (size_t i = 0; i < _stack_->count; i++) + _stack_->f_val->free(_stack_->buffer[i]); + } + + _stack_->alloc->free(_stack_->buffer); + _stack_->alloc->free(_stack_); +} + +void CMC_(PFX, _customize)(struct SNAME *_stack_, struct CMC_ALLOC_NODE_NAME *alloc, + struct CMC_CALLBACKS_NAME *callbacks) +{ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); + + if (!alloc) + _stack_->alloc = &cmc_alloc_node_default; + else + _stack_->alloc = alloc; + + CMC_CALLBACKS_ASSIGN(_stack_, callbacks); + + _stack_->flag = CMC_FLAG_OK; +} + +bool CMC_(PFX, _push)(struct SNAME *_stack_, V value) +{ + if (CMC_(PFX, _full)(_stack_)) + { + if (!CMC_(PFX, _resize)(_stack_, _stack_->capacity * 2)) + return false; + } + + _stack_->buffer[_stack_->count++] = value; + + _stack_->flag = CMC_FLAG_OK; + + CMC_CALLBACKS_CALL(_stack_, create); + + return true; +} + +bool CMC_(PFX, _pop)(struct SNAME *_stack_) +{ + if (CMC_(PFX, _empty)(_stack_)) + { + _stack_->flag = CMC_FLAG_EMPTY; + return false; + } + + _stack_->buffer[--_stack_->count] = (V){ 0 }; + + _stack_->flag = CMC_FLAG_OK; + + CMC_CALLBACKS_CALL(_stack_, delete); + + return true; +} + +V CMC_(PFX, _top)(struct SNAME *_stack_) +{ + if (CMC_(PFX, _empty)(_stack_)) + { + _stack_->flag = CMC_FLAG_EMPTY; + return (V){ 0 }; + } + + _stack_->flag = CMC_FLAG_OK; + + CMC_CALLBACKS_CALL(_stack_, read); + + return _stack_->buffer[_stack_->count - 1]; +} + +bool CMC_(PFX, _contains)(struct SNAME *_stack_, V value) +{ + _stack_->flag = CMC_FLAG_OK; + + bool result = false; + + for (size_t i = 0; i < _stack_->count; i++) + { + if (_stack_->f_val->cmp(_stack_->buffer[i], value) == 0) + { + result = true; + break; + } + } + + CMC_CALLBACKS_CALL(_stack_, read); + + return result; +} + +bool CMC_(PFX, _empty)(struct SNAME *_stack_) +{ + return _stack_->count == 0; +} + +bool CMC_(PFX, _full)(struct SNAME *_stack_) +{ + return _stack_->count >= _stack_->capacity; +} + +size_t CMC_(PFX, _count)(struct SNAME *_stack_) +{ + return _stack_->count; +} + +size_t CMC_(PFX, _capacity)(struct SNAME *_stack_) +{ + return _stack_->capacity; +} + +int CMC_(PFX, _flag)(struct SNAME *_stack_) +{ + return _stack_->flag; +} + +bool CMC_(PFX, _resize)(struct SNAME *_stack_, size_t capacity) +{ + if (_stack_->capacity == capacity) + goto success; + + if (capacity < _stack_->count) + { + _stack_->flag = CMC_FLAG_INVALID; + return false; + } + + V *new_buffer = _stack_->alloc->realloc(_stack_->buffer, sizeof(V) * capacity); + + if (!new_buffer) + { + _stack_->flag = CMC_FLAG_ALLOC; + return false; + } + + /* TODO zero out new slots */ + + _stack_->buffer = new_buffer; + _stack_->capacity = capacity; + +success: + + _stack_->flag = CMC_FLAG_OK; + + CMC_CALLBACKS_CALL(_stack_, resize); + + return true; +} + +struct SNAME *CMC_(PFX, _copy_of)(struct SNAME *_stack_) +{ + struct SNAME *result = CMC_(PFX, _new_custom)(_stack_->capacity, _stack_->f_val, _stack_->alloc, NULL); + + if (!result) + { + _stack_->flag = CMC_FLAG_ERROR; + return NULL; + } + + CMC_CALLBACKS_ASSIGN(result, _stack_->callbacks); + + if (_stack_->f_val->cpy) + { + for (size_t i = 0; i < _stack_->count; i++) + result->buffer[i] = _stack_->f_val->cpy(_stack_->buffer[i]); + } + else + memcpy(result->buffer, _stack_->buffer, sizeof(V) * _stack_->count); + + result->count = _stack_->count; + + _stack_->flag = CMC_FLAG_OK; + + return result; +} + +bool CMC_(PFX, _equals)(struct SNAME *_stack1_, struct SNAME *_stack2_) +{ + _stack1_->flag = CMC_FLAG_OK; + _stack2_->flag = CMC_FLAG_OK; + + if (_stack1_->count != _stack2_->count) + return false; + + for (size_t i = 0; i < _stack1_->count; i++) + { + if (_stack1_->f_val->cmp(_stack1_->buffer[i], _stack2_->buffer[i]) != 0) + return false; + } + + return true; +} \ No newline at end of file diff --git a/src/cmc/cmc/stack/ext/code.h b/src/cmc/cmc/stack/ext/code.h new file mode 100644 index 0000000..b61e4a4 --- /dev/null +++ b/src/cmc/cmc/stack/ext/code.h @@ -0,0 +1,318 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * INIT + * + * The part 'INIT' gives a new way of initializing a collection. The collection + * struct is not heap allocated, only its internal structure (nodes, buffers). + */ +#ifdef CMC_EXT_STACK_INIT + +struct SNAME CMC_(PFX, _init)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val) +{ + return CMC_(PFX, _init_custom)(capacity, f_val, NULL, NULL); +} + +struct SNAME CMC_(PFX, _init_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, + struct CMC_ALLOC_NODE_NAME *alloc, struct CMC_CALLBACKS_NAME *callbacks) +{ + CMC_CALLBACKS_MAYBE_UNUSED(callbacks); + + struct SNAME _stack_ = { 0 }; + + if (capacity < 1) + return _stack_; + + if (!f_val) + return _stack_; + + if (!alloc) + alloc = &cmc_alloc_node_default; + + _stack_.buffer = alloc->calloc(capacity, sizeof(V)); + + if (!_stack_.buffer) + return _stack_; + + _stack_.capacity = capacity; + _stack_.count = 0; + _stack_.flag = CMC_FLAG_OK; + _stack_.f_val = f_val; + _stack_.alloc = alloc; + CMC_CALLBACKS_ASSIGN(&_stack_, callbacks); + + return _stack_; +} + +void CMC_(PFX, _release)(struct SNAME _stack_) +{ + if (_stack_.f_val->free) + { + for (size_t i = 0; i < _stack_.count; i++) + _stack_.f_val->free(_stack_.buffer[i]); + } + + _stack_.alloc->free(_stack_.buffer); +} + +#endif /* CMC_EXT_STACK_INIT */ + +/** + * ITER + * + * Stack bi-directional iterator. + */ +#ifdef CMC_EXT_STACK_ITER + +struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME *target) +{ + struct CMC_DEF_ITER(SNAME) iter; + + iter.target = target; + iter.cursor = 0; + iter.start = true; + iter.end = CMC_(PFX, _empty)(target); + + if (!CMC_(PFX, _empty)(target)) + iter.cursor = target->count - 1; + + return iter; +} + +struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME *target) +{ + struct CMC_DEF_ITER(SNAME) iter; + + iter.target = target; + iter.cursor = 0; + iter.start = CMC_(PFX, _empty)(target); + iter.end = true; + + return iter; +} + +bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) +{ + return CMC_(PFX, _empty)(iter->target) || iter->start; +} + +bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) +{ + return CMC_(PFX, _empty)(iter->target) || iter->end; +} + +bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) +{ + if (!CMC_(PFX, _empty)(iter->target)) + { + iter->cursor = iter->target->count - 1; + iter->start = true; + iter->end = CMC_(PFX, _empty)(iter->target); + + return true; + } + + return false; +} + +bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) +{ + if (!CMC_(PFX, _empty)(iter->target)) + { + iter->cursor = 0; + iter->start = CMC_(PFX, _empty)(iter->target); + iter->end = true; + + return true; + } + + return false; +} + +bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) +{ + if (iter->end) + return false; + + if (iter->cursor == 0) + { + iter->end = true; + return false; + } + + iter->start = CMC_(PFX, _empty)(iter->target); + + iter->cursor--; + + return true; +} + +bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) +{ + if (iter->start) + return false; + + if (iter->cursor + 1 == iter->target->count) + { + iter->start = true; + return false; + } + + iter->end = CMC_(PFX, _empty)(iter->target); + + iter->cursor++; + + return true; +} + +/* Returns true only if the iterator moved */ +bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) +{ + if (iter->end) + return false; + + if (iter->cursor == 0) + { + iter->end = true; + return false; + } + + if (steps == 0 || iter->cursor < steps) + return false; + + iter->start = CMC_(PFX, _empty)(iter->target); + + iter->cursor -= steps; + + return true; +} + +/* Returns true only if the iterator moved */ +bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) +{ + if (iter->start) + return false; + + if (iter->cursor + 1 == iter->target->count) + { + iter->start = true; + return false; + } + + if (steps == 0 || iter->cursor + steps >= iter->target->count) + return false; + + iter->end = CMC_(PFX, _empty)(iter->target); + + iter->cursor += steps; + + return true; +} + +/* Returns true only if the iterator was able to be positioned at the */ +/* given index */ +bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) +{ + if (index >= iter->target->count) + return false; + + if (iter->cursor > index) + return CMC_(PFX, _iter_advance)(iter, iter->cursor - index); + else if (iter->cursor < index) + return CMC_(PFX, _iter_rewind)(iter, index - iter->cursor); + + return true; +} + +V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) +{ + if (CMC_(PFX, _empty)(iter->target)) + return (V){ 0 }; + + return iter->target->buffer[iter->cursor]; +} + +V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) +{ + if (CMC_(PFX, _empty)(iter->target)) + return NULL; + + return &(iter->target->buffer[iter->cursor]); +} + +size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) +{ + if (CMC_(PFX, _empty)(iter->target)) + return 0; + + return iter->target->count - 1 - iter->cursor; +} + +#endif /* CMC_EXT_STACK_ITER */ + +/** + * STR + * + * Print helper functions. + */ +#ifdef CMC_EXT_STACK_STR + +bool CMC_(PFX, _to_string)(struct SNAME *_stack_, FILE *fptr) +{ + struct SNAME *s_ = _stack_; + + return 0 <= fprintf(fptr, + "struct %s<%s> " + "at %p { " + "buffer:%p, " + "capacity:%" PRIuMAX ", " + "count:%" PRIuMAX ", " + "flag:%d, " + "f_val:%p, " + "alloc:%p, " + "callbacks:%p }", + CMC_TO_STRING(SNAME), CMC_TO_STRING(V), s_, s_->buffer, s_->capacity, s_->count, s_->flag, + s_->f_val, s_->alloc, CMC_CALLBACKS_GET(s_)); +} + +bool CMC_(PFX, _print)(struct SNAME *_stack_, FILE *fptr, const char *start, const char *separator, const char *end) +{ + fprintf(fptr, "%s", start); + + for (size_t i = _stack_->count; i > 0; i--) + { + if (!_stack_->f_val->str(fptr, _stack_->buffer[i - 1])) + return false; + + if (i - 1 != 0) + fprintf(fptr, "%s", separator); + } + + fprintf(fptr, "%s", end); + + return true; +} + +#endif /* CMC_EXT_STACK_STR */ diff --git a/src/cmc/cmc/stack/ext/header.h b/src/cmc/cmc/stack/ext/header.h new file mode 100644 index 0000000..bb8f372 --- /dev/null +++ b/src/cmc/cmc/stack/ext/header.h @@ -0,0 +1,80 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * INIT + * + * The part 'INIT' gives a new way of initializing a collection. The collection + * struct is not heap allocated, only its internal structure (nodes, buffers). + */ +#ifdef CMC_EXT_STACK_INIT + +struct SNAME CMC_(PFX, _init)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val); +struct SNAME CMC_(PFX, _init_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, + struct CMC_ALLOC_NODE_NAME *alloc, struct CMC_CALLBACKS_NAME *callbacks); +void CMC_(PFX, _release)(struct SNAME _stack_); + +#endif /* CMC_EXT_STACK_INIT */ + +/** + * ITER + * + * Stack bi-directional iterator. + */ +#ifdef CMC_EXT_STACK_ITER + +/* Iterator Initialization */ +struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME *target); +struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME *target); +/* Iterator State */ +bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); +bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); +/* Iterator Movement */ +bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); +bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); +bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); +bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); +bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); +bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); +bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); +/* Iterator Access */ +V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); +V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); +size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); + +#endif /* CMC_EXT_STACK_ITER */ + +/** + * STR + * + * Print helper functions. + */ +#ifdef CMC_EXT_STACK_STR + +/* Debug prints the struct to fptr */ +bool CMC_(PFX, _to_string)(struct SNAME *_stack_, FILE *fptr); +/* Prints each item in the stack as an array */ +bool CMC_(PFX, _print)(struct SNAME *_stack_, FILE *fptr, const char *start, const char *separator, const char *end); + +#endif /* CMC_EXT_STACK_STR */ diff --git a/src/cmc/cmc/stack/ext/struct.h b/src/cmc/cmc/stack/ext/struct.h new file mode 100644 index 0000000..81e7afd --- /dev/null +++ b/src/cmc/cmc/stack/ext/struct.h @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * ITER + * + * Stack bi-directional iterator. + */ +#ifdef CMC_EXT_STACK_ITER + +/* Stack Iterator */ +struct CMC_DEF_ITER(SNAME) +{ + /* Target stack */ + struct SNAME *target; + /* Cursor's position (index) */ + size_t cursor; + /* If the iterator has reached the start of the iteration */ + bool start; + /* If the iterator has reached the end of the iteration */ + bool end; +}; + +#endif /* CMC_EXT_STACK_ITER */ diff --git a/src/cmc/cmc/stack/header.h b/src/cmc/cmc/stack/header.h new file mode 100644 index 0000000..eaa6f13 --- /dev/null +++ b/src/cmc/cmc/stack/header.h @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* Collection Allocation and Deallocation */ +struct SNAME *CMC_(PFX, _new)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val); +struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, + struct CMC_ALLOC_NODE_NAME *alloc, struct CMC_CALLBACKS_NAME *callbacks); +void CMC_(PFX, _clear)(struct SNAME *_stack_); +void CMC_(PFX, _free)(struct SNAME *_stack_); +/* Customization of Allocation and Callbacks */ +void CMC_(PFX, _customize)(struct SNAME *_stack_, struct CMC_ALLOC_NODE_NAME *alloc, + struct CMC_CALLBACKS_NAME *callbacks); +/* Collection Input and Output */ +bool CMC_(PFX, _push)(struct SNAME *_stack_, V value); +bool CMC_(PFX, _pop)(struct SNAME *_stack_); +/* Element Access */ +V CMC_(PFX, _top)(struct SNAME *_stack_); +/* Collection State */ +bool CMC_(PFX, _contains)(struct SNAME *_stack_, V value); +bool CMC_(PFX, _empty)(struct SNAME *_stack_); +bool CMC_(PFX, _full)(struct SNAME *_stack_); +size_t CMC_(PFX, _count)(struct SNAME *_stack_); +size_t CMC_(PFX, _capacity)(struct SNAME *_stack_); +int CMC_(PFX, _flag)(struct SNAME *_stack_); +/* Collection Utility */ +bool CMC_(PFX, _resize)(struct SNAME *_stack_, size_t capacity); +struct SNAME *CMC_(PFX, _copy_of)(struct SNAME *_stack_); +bool CMC_(PFX, _equals)(struct SNAME *_stack1_, struct SNAME *_stack2_); diff --git a/src/cmc/cmc/stack/struct.h b/src/cmc/cmc/stack/struct.h new file mode 100644 index 0000000..3160683 --- /dev/null +++ b/src/cmc/cmc/stack/struct.h @@ -0,0 +1,58 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* Stack Structure */ +struct SNAME +{ + /* Dynamic array of elements */ + V *buffer; + /* Current array capacity */ + size_t capacity; + /* Current amount of elements */ + size_t count; + /* Flags indicating errors or success */ + int flag; + /* Value function table */ + struct CMC_DEF_FVAL(SNAME) * f_val; + /* Custom allocation functions */ + struct CMC_ALLOC_NODE_NAME *alloc; + /* Custom callback functions */ + CMC_CALLBACKS_DECL; +}; +/* Value struct function table */ +struct CMC_DEF_FVAL(SNAME) +{ + /* Comparator function */ + CMC_DEF_FTAB_CMP(V); + /* Copy function */ + CMC_DEF_FTAB_CPY(V); + /* To string function */ + CMC_DEF_FTAB_STR(V); + /* Free from memory function */ + CMC_DEF_FTAB_FREE(V); + /* Hash function */ + CMC_DEF_FTAB_HASH(V); + /* Priority function */ + CMC_DEF_FTAB_PRI(V); +}; diff --git a/src/cmc/cmc_deque.h b/src/cmc/cmc_deque.h new file mode 100644 index 0000000..5d16067 --- /dev/null +++ b/src/cmc/cmc_deque.h @@ -0,0 +1,88 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * cmc_deque.h + * + * Creation Date: 20/03/2019 + * + * Authors: + * Leonardo Vencovsky (https://github.com/LeoVen) + * + */ + +/** + * Deque + * + * A Deque (double-ended queue) is a linear data structure that is able to add + * or remove elements from both ends. It can also be thought of a double-ended + * stack since you can push and pop elements from two ends. The Deque can also + * be used as a Queue. + * + * There is no random access for a Deque. The only elements accessible are the + * front element and the back. + * + * Implementation + * + * This implementation uses a circular buffer (ring buffer or cyclic buffer) in + * order to operate on O(1) for push and pop on either ends (only case where it + * takes longer than O(1) is when the buffer is reallocated). If it was + * implemented as a regular array, adding or removing elements from the front + * would take O(N) due to the need to shift all elements in the deque. + */ + +#include "cor/core.h" + +/** + * Used values + * V - deque data type + * SNAME - struct name and prefix of other related structs + * PFX - functions prefix + */ + +/* Structs definition */ +#include "cmc/deque/struct.h" + +/* Function declaration */ +#include "cmc/deque/header.h" + +/* Function implementation */ +#include "cmc/deque/code.h" + +/** + * Extensions + * + * INIT - Initializes the struct on the stack + * ITER - Deque iterator + * STR - Print helper functions + */ +#define CMC_EXT_CMC_DEQUE_PARTS INIT, ITER, STR +/**/ +#include "cmc/deque/ext/struct.h" +/**/ +#include "cmc/deque/ext/header.h" +/**/ +#include "cmc/deque/ext/code.h" + +#include "cor/undef.h" diff --git a/src/cmc/cmc_list.h b/src/cmc/cmc_list.h new file mode 100644 index 0000000..0a4ad9f --- /dev/null +++ b/src/cmc/cmc_list.h @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * cmc_list.h + * + * Creation Date: 12/02/2019 + * + * Authors: + * Leonardo Vencovsky (https://github.com/LeoVen) + * + */ + +/** + * List + * + * A List is a Dynamic Array that store its elements contiguously. It has an + * internal buffer that is pre-allocated with a greater capacity than necessary + * in order to foresee new elements being added. The items can be added at both + * ends of the list and at the middle (with a given index). + * + * Insertions at the start are more costly as it is necessary to shift all + * elements one position to the right to give space to a new element being added + * at index 0. Insertions at the end are instantaneous as long as there is + * enough space in the buffer. Insertions at the middle will be based on an + * index. The index represents where the element being added will be located + * once the operation ends. This operation might also need to shift elements. It + * is also possible to add arrays of elements in the list. + * + * When the buffer is filled, it is reallocated with a greater capacity, usually + * being doubled. + * + * Removing elements follows the same principle. Removing the front element will + * require to shift all other elements one position to the left, thus being + * slower than removing from the end in which is done in constant time. Removing + * elements in the middle of the list will also require shifting elements to the + * left. Is is also possible to remove a range of elements or extract them, + * creating a new list with the removed items. + * + * The iterator is a simple structure that is capable of going back and + * forwards. Any modifications to the target list during iteration is considered + * undefined behavior. Its sole purpose is to facilitate navigation through a + * list. + */ + +#include "cor/core.h" + +/** + * Used values + * V - list data type + * SNAME - struct name and prefix of other related structs + * PFX - functions prefix + */ + +/* Structs definition */ +#include "cmc/list/struct.h" + +/* Function declaration */ +#include "cmc/list/header.h" + +/* Function implementation */ +#include "cmc/list/code.h" + +/** + * Extensions + * + * ITER - List iterator + * SEQ - Push and pop sequence of items + * STR - Print helper functions + */ +#define CMC_EXT_CMC_LIST_PARTS INIT, ITER, SEQ, STR +/**/ +#include "cmc/list/ext/struct.h" +/**/ +#include "cmc/list/ext/header.h" +/**/ +#include "cmc/list/ext/code.h" + +#include "cor/undef.h" diff --git a/src/cmc/cmc_stack.h b/src/cmc/cmc_stack.h new file mode 100644 index 0000000..c86ca3b --- /dev/null +++ b/src/cmc/cmc_stack.h @@ -0,0 +1,84 @@ +/** + * Copyright (c) 2019 Leonardo Vencovsky + * + * This file is part of the C Macro Collections Libray. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * cmc_stack.h + * + * Creation Date: 14/02/2019 + * + * Authors: + * Leonardo Vencovsky (https://github.com/LeoVen) + * + */ + +/** + * Stack + * + * A Stack is a Last-in First-out (or First-in Last-out) data structure used in + * a variety of algorithms. It is a Dynamic Array that can only add or remove + * its elements at the end of the buffer, in this case, it represents the top of + * the stack. + * + * It has three main functions: `push` which adds an element at the top of the + * stack; `pop` which removes the top element from the stack; and `top` which + * returns the top element without removing it (it is also sometimes called + * `peek`). + * + * A Stack is used in algorithms like backtracking, depth-first search, + * expression evaluation, syntax parsing and many more. + */ + +#include "cor/core.h" + +/** + * Used values + * V - Stack data type + * SNAME - struct name and prefix of other related structs + * PFX - functions prefix + */ + +/* Structs definition */ +#include "cmc/stack/struct.h" + +/* Function declaration */ +#include "cmc/stack/header.h" + +/* Function implementation */ +#include "cmc/stack/code.h" + +/** + * Extensions + * + * ITER - Stack iterator + * STR - Print helper functions + */ +#define CMC_EXT_CMC_STACK_PARTS INIT, ITER, STR +/**/ +#include "cmc/stack/ext/struct.h" +/**/ +#include "cmc/stack/ext/header.h" +/**/ +#include "cmc/stack/ext/code.h" + +#include "cor/undef.h" diff --git a/src/cor_alloc.h b/src/cmc/cor/alloc.h similarity index 98% rename from src/cor_alloc.h rename to src/cmc/cor/alloc.h index b3d0eee..3c715e1 100644 --- a/src/cor_alloc.h +++ b/src/cmc/cor/alloc.h @@ -23,7 +23,7 @@ */ /** - * cor_alloc.h + * alloc.h * * Creation Date: 24/05/2020 * @@ -41,7 +41,7 @@ #define CMC_ALLOC_NODE_NAME cmc_alloc_node #endif -#include "cor_core.h" +#include "core.h" /** * struct cmc_alloc_node diff --git a/src/cor_bitset.h b/src/cmc/cor/bitset.h similarity index 85% rename from src/cor_bitset.h rename to src/cmc/cor/bitset.h index a42e583..d4b3fb5 100644 --- a/src/cor_bitset.h +++ b/src/cmc/cor/bitset.h @@ -23,7 +23,7 @@ */ /** - * cor_bitset.h + * bitset.h * * Creation Date: 20/05/2020 * @@ -57,10 +57,10 @@ typedef CMC_BITSET_WORD_TYPE cmc_bitset_word; static inline size_t cmc_bidx_to_widx(size_t idx) { /* Calculate how many shifts based on the size of cmc_bitset_word */ - static const size_t shift = - ((sizeof(cmc_bitset_word) * 8) >> 6) > 0 - ? 6 - : ((sizeof(cmc_bitset_word) * 8) >> 5) > 0 ? 5 : ((sizeof(cmc_bitset_word) * 8) >> 4) > 0 ? 4 : 3; + static const size_t shift = ((sizeof(cmc_bitset_word) * 8) >> 6) > 0 ? 6 + : ((sizeof(cmc_bitset_word) * 8) >> 5) > 0 ? 5 + : ((sizeof(cmc_bitset_word) * 8) >> 4) > 0 ? 4 + : 3; return idx >> shift; } diff --git a/src/cor_callbacks.h b/src/cmc/cor/callbacks.h similarity index 99% rename from src/cor_callbacks.h rename to src/cmc/cor/callbacks.h index 4d21481..90648b4 100644 --- a/src/cor_callbacks.h +++ b/src/cmc/cor/callbacks.h @@ -23,7 +23,7 @@ */ /** - * cor_callbacks.h + * callbacks.h * * Creation Date: 24/05/2020 * diff --git a/src/cor_core.h b/src/cmc/cor/core.h similarity index 72% rename from src/cor_core.h rename to src/cmc/cor/core.h index 09bbb74..bdd4002 100644 --- a/src/cor_core.h +++ b/src/cmc/cor/core.h @@ -23,7 +23,7 @@ */ /** - * cor_core.h + * core.h * * Creation Date: 17/03/2020 * @@ -40,18 +40,11 @@ * - CMC_TO_STRING * - CMC_INTERNAL_PREFIX_[ITER|NODE|ENTRY|FKEY|FVAL] * - CMC_DEF_[ITER|NODE|ENTRY|FKEY|FVAL] - * - CMC_PARAM_[PFX|SNAME|SIZE|K|V] */ #ifndef CMC_COR_CORE_H #define CMC_COR_CORE_H -#if defined(__GNUC__) || defined(__clang__) -#define CMC_UNUSED __attribute__((__unused__)) -#else -#define CMC_UNUSED -#endif - #include #include #include @@ -59,10 +52,11 @@ #include #include -#include "cor_alloc.h" -#include "cor_callbacks.h" -#include "cor_flags.h" -#include "cor_ftable.h" +#if defined(__GNUC__) || defined(__clang__) +#define CMC_UNUSED __attribute__((__unused__)) +#else +#define CMC_UNUSED +#endif #define CMC__(A, B) A##B #define CMC_(A, B) CMC__(A, B) @@ -70,6 +64,11 @@ #define CMC_TO_STRING_(X) #X #define CMC_TO_STRING(X) CMC_TO_STRING_(X) +#include "alloc.h" +#include "callbacks.h" +#include "flags.h" +#include "ftable.h" + #if defined(CMC_CAMEL_CASE) #define CMC_INTERNAL_PREFIX_ITER Iter #define CMC_INTERNAL_PREFIX_NODE Node @@ -90,36 +89,4 @@ #define CMC_DEF_FVAL(SNAME) CMC_(SNAME, CMC_INTERNAL_PREFIX_FVAL) #define CMC_DEF_FKEY(SNAME) CMC_(SNAME, CMC_INTERNAL_PREFIX_FKEY) -/** - * Code to get specific arguments from tuples. - */ -#define CMC_TUP_0_(A, ...) A -#define CMC_TUP_0(TUP) CMC_TUP_0_ TUP -#define CMC_TUP_1_(A, B, ...) B -#define CMC_TUP_1(TUP) CMC_TUP_1_ TUP -#define CMC_TUP_2_(A, B, C, ...) C -#define CMC_TUP_2(TUP) CMC_TUP_2_ TUP -#define CMC_TUP_3_(A, B, C, D, ...) D -#define CMC_TUP_3(TUP) CMC_TUP_3_ TUP -#define CMC_TUP_4_(A, B, C, D, E, ...) E -#define CMC_TUP_4(TUP) CMC_TUP_4_ TUP - -/** - * A PARAM is a unified way to pass arguments to all macros that generate code. - * It is a tuple that contains the following parameters in order: - * - * PFX - Functions prefix - * SNAME - `struct` name - * SIZE - Size for SAC library - * K - Key type - * V - Value type - * - * PARAMS := (PFX, SNAME, SIZE, K, V) - */ -#define CMC_PARAM_PFX CMC_TUP_0 -#define CMC_PARAM_SNAME CMC_TUP_1 -#define CMC_PARAM_SIZE CMC_TUP_2 -#define CMC_PARAM_K CMC_TUP_3 -#define CMC_PARAM_V CMC_TUP_4 - #endif /* CMC_COR_CORE_H */ diff --git a/src/cor_flags.h b/src/cmc/cor/flags.h similarity index 92% rename from src/cor_flags.h rename to src/cmc/cor/flags.h index c3b2746..f9ad190 100644 --- a/src/cor_flags.h +++ b/src/cmc/cor/flags.h @@ -23,7 +23,7 @@ */ /** - * cor_flags.h + * flags.h * * Creation Date: 14/05/2020 * @@ -35,7 +35,7 @@ #ifndef CMC_COR_FLAGS_H #define CMC_COR_FLAGS_H -#include "cor_core.h" +#include "core.h" /** * enum cmc_flags @@ -64,7 +64,7 @@ enum cmc_flags * * Maps the error codes to their character representation. */ -CMC_UNUSED static const char *cmc_flags_to_str[11] = { "OK", "ALLOC", "EMPTY", "NOT_FOUND", "INVALID", - "RANGE", "DUPLICATE", "ERROR", "THREAD", "MUTEX", "FULL" }; +CMC_UNUSED static const char *cmc_flags_to_str[11] = { "OK", "ALLOC", "EMPTY", "NOT_FOUND", "INVALID", "RANGE", + "DUPLICATE", "ERROR", "THREAD", "MUTEX", "FULL" }; #endif /* CMC_COR_FLAGS_H */ diff --git a/src/cor_ftable.h b/src/cmc/cor/ftable.h similarity index 99% rename from src/cor_ftable.h rename to src/cmc/cor/ftable.h index 206dd1f..52d9f1d 100644 --- a/src/cor_ftable.h +++ b/src/cmc/cor/ftable.h @@ -23,7 +23,7 @@ */ /** - * cor_ftable.h + * ftable.h * * Creation Date: 27/05/2020 * diff --git a/src/cor_hashtable.h b/src/cmc/cor/hashtable.h similarity index 98% rename from src/cor_hashtable.h rename to src/cmc/cor/hashtable.h index 816e07d..f516e5e 100644 --- a/src/cor_hashtable.h +++ b/src/cmc/cor/hashtable.h @@ -23,7 +23,7 @@ */ /** - * cor_hashtable.h + * hashtable.h * * Creation Date: 17/03/2020 * @@ -39,7 +39,7 @@ #ifndef CMC_COR_HASHTABLE_H #define CMC_COR_HASHTABLE_H -#include "cor_core.h" +#include "core.h" /** * CMC_ENTRY_DELETED diff --git a/src/cor_heap.h b/src/cmc/cor/heap.h similarity index 99% rename from src/cor_heap.h rename to src/cmc/cor/heap.h index b395fe9..1b1ff16 100644 --- a/src/cor_heap.h +++ b/src/cmc/cor/heap.h @@ -23,7 +23,7 @@ */ /** - * cor_heap.h + * heap.h * * Creation Date: 01/06/2020 * diff --git a/src/ext_sac_list.h b/src/cmc/cor/undef.h similarity index 67% rename from src/ext_sac_list.h rename to src/cmc/cor/undef.h index 65f56a1..74bce3f 100644 --- a/src/ext_sac_list.h +++ b/src/cmc/cor/undef.h @@ -23,34 +23,41 @@ */ /** - * ext_sac_list.h + * prelude.h * - * Creation Date: 06/10/2020 + * Creation Date: 12/01/2023 * * Authors: * Leonardo Vencovsky (https://github.com/LeoVen) * */ -#ifndef CMC_EXT_SAC_LIST_H -#define CMC_EXT_SAC_LIST_H - -#include "cor_core.h" - /** - * All the EXT parts of SAC List. + * Common undefs */ -#define CMC_EXT_SAC_LIST_PARTS PLACEHOLDER -#define CMC_EXT_SAC_LIST_PLACEHOLDER(ACCESS, FILE, PARAMS) \ - CMC_(CMC_(CMC_EXT_SAC_LIST_PLACEHOLDER_, ACCESS), CMC_(_, FILE))(PARAMS) +#ifndef CMC_ARGS_FALLTHROUGH -#define CMC_EXT_SAC_LIST_PLACEHOLDER_PUBLIC_HEADER(PARAMS) +#undef V +#undef K +#undef PFX +#undef SNAME +#undef SIZE -#define CMC_EXT_SAC_LIST_PLACEHOLDER_PUBLIC_SOURCE(PARAMS) +/* Deque */ +#undef CMC_EXT_DEQUE_INIT +#undef CMC_EXT_DEQUE_ITER +#undef CMC_EXT_DEQUE_STR -#define CMC_EXT_SAC_LIST_PLACEHOLDER_PRIVATE_HEADER(PARAMS) +/* List */ +#undef CMC_EXT_LIST_INIT +#undef CMC_EXT_LIST_ITER +#undef CMC_EXT_LIST_SEQ +#undef CMC_EXT_LIST_STR -#define CMC_EXT_SAC_LIST_PLACEHOLDER_PRIVATE_SOURCE(PARAMS) +/* Stack */ +#undef CMC_EXT_STACK_INIT +#undef CMC_EXT_STACK_ITER +#undef CMC_EXT_STACK_STR -#endif /* CMC_EXT_SAC_LIST_H */ +#endif diff --git a/src/utl_assert.h b/src/cmc/utl/assert.h similarity index 99% rename from src/utl_assert.h rename to src/cmc/utl/assert.h index 0237caa..4f469e6 100644 --- a/src/utl_assert.h +++ b/src/cmc/utl/assert.h @@ -23,7 +23,7 @@ */ /** - * utl_assert.h + * assert.h * * Creation Date: 27/06/2019 * @@ -80,7 +80,7 @@ #include #include -#include "cor_core.h" +#include "../cor/core.h" #define CMC_ASSERT_GLUE_(dtype, assertion) cmc_assert_##assertion##_##dtype #define CMC_ASSERT_GLUE(dtype, assertion) CMC_ASSERT_GLUE_(dtype, assertion) diff --git a/src/utl_foreach.h b/src/cmc/utl/foreach.h similarity index 96% rename from src/utl_foreach.h rename to src/cmc/utl/foreach.h index f276225..f4c52a9 100644 --- a/src/utl_foreach.h +++ b/src/cmc/utl/foreach.h @@ -38,13 +38,13 @@ * PFX - Functions prefix * SNAME - Struct name * ITERNAME - Iterator variable name - * TARGET - Target variable + * TARGET - Target data structure variable name */ #ifndef CMC_UTL_FOREACH_H #define CMC_UTL_FOREACH_H -#include "cor_core.h" +#include "../cor/core.h" #define CMC_FOREACH(PFX, SNAME, ITERNAME, TARGET) \ for (struct CMC_DEF_ITER(SNAME) ITERNAME = CMC_(PFX, _iter_start)(TARGET); !CMC_(PFX, _iter_at_end)(&ITERNAME); \ diff --git a/src/utl_futils.h b/src/cmc/utl/futils.h similarity index 99% rename from src/utl_futils.h rename to src/cmc/utl/futils.h index 206e1b6..6921e42 100644 --- a/src/utl_futils.h +++ b/src/cmc/utl/futils.h @@ -229,7 +229,7 @@ static inline bool cmc_double_str(FILE *file, double element) static inline bool cmc_str_str(FILE *file, char *element) { - return fprintf(file, "%s", element) > 0; + return fprintf(file, "\"%s\"", element) > 0; } /** diff --git a/src/utl_log.h b/src/cmc/utl/log.h similarity index 99% rename from src/utl_log.h rename to src/cmc/utl/log.h index e874994..35f46ba 100644 --- a/src/utl_log.h +++ b/src/cmc/utl/log.h @@ -88,7 +88,7 @@ #include #include -#include "cor_core.h" +#include "../cor/core.h" static const char *cmc_log_names[] = { "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL" }; diff --git a/src/utl_mutex.h b/src/cmc/utl/mutex.h similarity index 99% rename from src/utl_mutex.h rename to src/cmc/utl/mutex.h index 9bb9eef..30edf75 100644 --- a/src/utl_mutex.h +++ b/src/cmc/utl/mutex.h @@ -51,7 +51,7 @@ #include -#include "cor_flags.h" +#include "../cor/flags.h" #if defined(_WIN32) #define CMC_MUTEX_WINDOWS diff --git a/src/utl_test.h b/src/cmc/utl/test.h similarity index 99% rename from src/utl_test.h rename to src/cmc/utl/test.h index 065fca0..0cbad16 100644 --- a/src/utl_test.h +++ b/src/cmc/utl/test.h @@ -66,9 +66,9 @@ #include #include -#include "cor_core.h" -#include "utl_assert.h" -#include "utl_timer.h" +#include "../cor/core.h" +#include "assert.h" +#include "timer.h" struct cmc_test_info { diff --git a/src/utl_thread.h b/src/cmc/utl/thread.h similarity index 99% rename from src/utl_thread.h rename to src/cmc/utl/thread.h index 345b9af..24efc9a 100644 --- a/src/utl_thread.h +++ b/src/cmc/utl/thread.h @@ -50,7 +50,7 @@ #include #include -#include "cor_flags.h" +#include "../cor/flags.h" #if defined(_WIN32) #define CMC_THREAD_WINDOWS diff --git a/src/utl_timer.h b/src/cmc/utl/timer.h similarity index 100% rename from src/utl_timer.h rename to src/cmc/utl/timer.h diff --git a/src/cmc_bitset.h b/src/cmc_bitset.h deleted file mode 100644 index 17d1bca..0000000 --- a/src/cmc_bitset.h +++ /dev/null @@ -1,598 +0,0 @@ -/** - * Copyright (c) 2019 Leonardo Vencovsky - * - * This file is part of the C Macro Collections Libray. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * cmc_bitset.h - * - * Creation Date: 30/04/2020 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -/** - * BitSet - * - * A Bit Set is an array where each bit can be individually modified and queried - * by using bitwise operators such as |, &, ^, ~, >> and << (or, and, xor, not, - * right shift, left shift respectively). - * - * Implementation - * - * This BitSet implementation uses an array of type cmc_bitset_word which can be - * typedefed to any unsigned type such as uint8_t, uint16_t, uint32_t, uint64_t, - * size_t, etc. The BitSet does not make use of K or V. Because of that, it also - * doesn't have Functions Tables. - * - * The BitSet is initialized with a custom capacity but, if a bit index accessed - * is greater than the total capacity, the BitSet will resize. This means that - * the BitSet will try to guarantee that every bit index is accessible, as long - * as there is enough memory. - */ - -#ifndef CMC_CMC_BITSET_H -#define CMC_CMC_BITSET_H - -/* ------------------------------------------------------------------------- - * Core functionalities of the C Macro Collections Library - * ------------------------------------------------------------------------- */ -#include "cor_core.h" - -/* ------------------------------------------------------------------------- - * BitSet Implementation - * ------------------------------------------------------------------------- */ -#include "cor_bitset.h" - -/** - * Core BitSet implementation - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_CMC_BITSET_CORE(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_CMC_BITSET_CORE_, ACCESS), CMC_(_, FILE))(PARAMS) - -/* PRIVATE or PUBLIC solver */ -#define CMC_CMC_BITSET_CORE_PUBLIC_HEADER(PARAMS) \ - CMC_CMC_BITSET_CORE_STRUCT(PARAMS) \ - CMC_CMC_BITSET_CORE_HEADER(PARAMS) - -#define CMC_CMC_BITSET_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_BITSET_CORE_SOURCE(PARAMS) - -#define CMC_CMC_BITSET_CORE_PRIVATE_HEADER(PARAMS) \ - struct CMC_PARAM_SNAME(PARAMS); \ - CMC_CMC_BITSET_CORE_HEADER(PARAMS) - -#define CMC_CMC_BITSET_CORE_PRIVATE_SOURCE(PARAMS) \ - CMC_CMC_BITSET_CORE_STRUCT(PARAMS) \ - CMC_CMC_BITSET_CORE_SOURCE(PARAMS) - -/* Lowest level API */ -#define CMC_CMC_BITSET_CORE_STRUCT(PARAMS) CMC_CMC_BITSET_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS)) - -#define CMC_CMC_BITSET_CORE_HEADER(PARAMS) CMC_CMC_BITSET_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS)) - -#define CMC_CMC_BITSET_CORE_SOURCE(PARAMS) CMC_CMC_BITSET_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS)) - -/* ------------------------------------------------------------------------- - * Struct - * ------------------------------------------------------------------------- */ -#define CMC_CMC_BITSET_CORE_STRUCT_(PFX, SNAME) \ -\ - /* BitSet Structure */ \ - struct SNAME \ - { \ - /* Dynamic Array of Bits */ \ - cmc_bitset_word *buffer; \ -\ - /* Current array capacity */ \ - size_t capacity; \ -\ - /* Currently used bits */ \ - /* This should always be true: */ \ - /* capacity - count < sizeof(cmc_bitset_word) * CHAR_BIT */ \ - size_t count; \ -\ - /* Flags indicating errors or success */ \ - int flag; \ -\ - /* Custom allocation functions */ \ - struct CMC_ALLOC_NODE_NAME *alloc; \ -\ - /* Custom callback functions */ \ - CMC_CALLBACKS_DECL; \ - }; - -/* ------------------------------------------------------------------------- - * Header - * ------------------------------------------------------------------------- */ -#define CMC_CMC_BITSET_CORE_HEADER_(PFX, SNAME) \ -\ - /* BitSet Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target bitset */ \ - struct SNAME *target; \ -\ - /* Cursor's position (index) */ \ - size_t cursor; \ -\ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ -\ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ -\ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(size_t n_bits); \ - struct SNAME *CMC_(PFX, _new_custom)(size_t n_bits, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks); \ - struct SNAME CMC_(PFX, _init)(size_t n_bits); \ - struct SNAME CMC_(PFX, _init_custom)(size_t n_bits, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks); \ - void CMC_(PFX, _free)(struct SNAME * _bitset_); \ - void CMC_(PFX, _release)(struct SNAME _bitset_); \ - void CMC_(PFX, _customize)(struct SNAME * _bitset_, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _set)(struct SNAME * _bitset_, size_t bit_index); \ - bool CMC_(PFX, _set_range)(struct SNAME * _bitset_, size_t from, size_t to); \ - bool CMC_(PFX, _clear)(struct SNAME * _bitset_, size_t bit_index); \ - bool CMC_(PFX, _clear_range)(struct SNAME * _bitset_, size_t from, size_t to); \ - bool CMC_(PFX, _flip)(struct SNAME * _bitset_, size_t bit_index); \ - bool CMC_(PFX, _flip_range)(struct SNAME * _bitset_, size_t from, size_t to); \ - bool CMC_(PFX, _put)(struct SNAME * _bitset_, size_t bit_index, bool state); \ - bool CMC_(PFX, _put_range)(struct SNAME * _bitset_, size_t from, size_t to, bool state); \ - bool CMC_(PFX, _set_all)(struct SNAME * _bitset_); \ - bool CMC_(PFX, _clear_all)(struct SNAME * _bitset_); \ - bool CMC_(PFX, _flip_all)(struct SNAME * _bitset_); \ - /* Element Access */ \ - bool CMC_(PFX, _get)(struct SNAME * _bitset_, size_t bit_index); \ - /* Collection State */ \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _bitset_, size_t n_bits); \ -\ - /* Iterator Functions */ \ - /* Iterator Initialization */ \ - /* Iterator State */ \ - /* Iterator Movement */ \ - /* Iterator Access */ - -/* ------------------------------------------------------------------------- - * Source - * ------------------------------------------------------------------------- */ -#define CMC_CMC_BITSET_CORE_SOURCE_(PFX, SNAME) \ -\ - /* Implementation Detail Functions */ \ - bool CMC_(PFX, _impl_resize)(struct SNAME * _bitset_, size_t n_bits, bool do_resize); \ -\ - struct SNAME *CMC_(PFX, _new)(size_t n_bits) \ - { \ - return CMC_(PFX, _new_custom)(n_bits, NULL, NULL); \ - } \ -\ - struct SNAME *CMC_(PFX, _new_custom)(size_t n_bits, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - if (n_bits < 1) \ - return NULL; \ -\ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ -\ - size_t capacity = cmc_bidx_to_widx(n_bits - 1) + 1; \ -\ - struct SNAME *_bitset_ = alloc->malloc(sizeof(struct SNAME)); \ -\ - if (!_bitset_) \ - return NULL; \ -\ - _bitset_->buffer = alloc->calloc(capacity, sizeof(cmc_bitset_word)); \ -\ - if (!_bitset_->buffer) \ - { \ - alloc->free(_bitset_); \ - return NULL; \ - } \ -\ - _bitset_->capacity = capacity; \ - _bitset_->flag = CMC_FLAG_OK; \ - _bitset_->alloc = alloc; \ - CMC_CALLBACKS_ASSIGN(_bitset_, callbacks); \ -\ - return _bitset_; \ - } \ -\ - struct SNAME CMC_(PFX, _init)(size_t n_bits) \ - { \ - return CMC_(PFX, _init_custom)(n_bits, NULL, NULL); \ - } \ -\ - struct SNAME CMC_(PFX, _init_custom)(size_t n_bits, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * CMC_UNUSED(callbacks)) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - struct SNAME _bitset_ = { 0 }; \ -\ - if (n_bits < 1) \ - return _bitset_; \ -\ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ -\ - size_t capacity = cmc_bidx_to_widx(n_bits - 1) + 1; \ -\ - _bitset_.buffer = alloc->calloc(capacity, sizeof(cmc_bitset_word)); \ -\ - if (!_bitset_.buffer) \ - return _bitset_; \ -\ - _bitset_.capacity = capacity; \ - _bitset_.flag = CMC_FLAG_OK; \ - _bitset_.alloc = alloc; \ - CMC_CALLBACKS_ASSIGN(&_bitset_, callbacks); \ -\ - return _bitset_; \ - } \ -\ - void CMC_(PFX, _free)(struct SNAME * _bitset_) \ - { \ - free(_bitset_->buffer); \ - free(_bitset_); \ - } \ -\ - void CMC_(PFX, _release)(struct SNAME _bitset_) \ - { \ - free(_bitset_.buffer); \ - } \ -\ - void CMC_(PFX, _customize)(struct SNAME * _bitset_, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - if (!alloc) \ - _bitset_->alloc = &cmc_alloc_node_default; \ - else \ - _bitset_->alloc = alloc; \ -\ - CMC_CALLBACKS_ASSIGN(_bitset_, callbacks); \ -\ - _bitset_->flag = CMC_FLAG_OK; \ - } \ -\ - bool CMC_(PFX, _set)(struct SNAME * _bitset_, size_t bit_index) \ - { \ - if (!CMC_(PFX, _impl_resize)(_bitset_, bit_index + 1, false)) \ - return false; \ -\ - /* How many bits in a word */ \ - const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ -\ - size_t i = cmc_bidx_to_widx(bit_index); \ -\ - _bitset_->buffer[i] |= ((cmc_bitset_word)1) << (bit_index % bits); \ -\ - _bitset_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_bitset_, create); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _set_range)(struct SNAME * _bitset_, size_t from, size_t to) \ - { \ - if (to < from) \ - { \ - _bitset_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ -\ - if (!CMC_(PFX, _impl_resize)(_bitset_, to + 1, false)) \ - return false; \ -\ - size_t start_index = cmc_bidx_to_widx(from); \ - size_t end_index = cmc_bidx_to_widx(to); \ -\ - /* How many bits in a word */ \ - const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ -\ - /* 1111 ... 1111 */ \ - const cmc_bitset_word ones = ~((cmc_bitset_word)0); \ -\ - cmc_bitset_word shift_start = from % bits; \ - cmc_bitset_word shift_end = (cmc_bitset_word)(-(to + 1)) % bits; \ -\ - cmc_bitset_word start_mask = ones << shift_start; \ - cmc_bitset_word end_mask = ones >> shift_end; \ -\ - if (start_index == end_index) \ - { \ - _bitset_->buffer[end_index] |= (start_mask & end_mask); \ - } \ - else \ - { \ - _bitset_->buffer[start_index] |= start_mask; \ -\ - for (size_t i = start_index + 1; i < end_index; i++) \ - _bitset_->buffer[i] |= ~((cmc_bitset_word)0); \ -\ - _bitset_->buffer[end_index] |= end_mask; \ - } \ -\ - _bitset_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_bitset_, create); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _clear)(struct SNAME * _bitset_, size_t bit_index) \ - { \ - if (!CMC_(PFX, _impl_resize)(_bitset_, bit_index + 1, false)) \ - return false; \ -\ - /* How many bits in a word */ \ - const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ -\ - size_t i = cmc_bidx_to_widx(bit_index); \ -\ - _bitset_->buffer[i] &= ~(((cmc_bitset_word)1) << (bit_index % bits)); \ -\ - _bitset_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_bitset_, delete); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _clear_range)(struct SNAME * _bitset_, size_t from, size_t to) \ - { \ - if (to < from) \ - { \ - _bitset_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ -\ - if (!CMC_(PFX, _impl_resize)(_bitset_, to + 1, false)) \ - return false; \ -\ - size_t start_index = cmc_bidx_to_widx(from); \ - size_t end_index = cmc_bidx_to_widx(to); \ -\ - /* How many bits in a word */ \ - const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ -\ - /* 1111 ... 1111 */ \ - const cmc_bitset_word ones = ~((cmc_bitset_word)0); \ -\ - cmc_bitset_word shift_start = from % bits; \ - cmc_bitset_word shift_end = (cmc_bitset_word)(-(to + 1)) % bits; \ -\ - cmc_bitset_word start_mask = ones << shift_start; \ - cmc_bitset_word end_mask = ones >> shift_end; \ -\ - if (start_index == end_index) \ - { \ - _bitset_->buffer[end_index] &= ~(start_mask & end_mask); \ - } \ - else \ - { \ - _bitset_->buffer[start_index] &= ~start_mask; \ -\ - for (size_t i = start_index + 1; i < end_index; i++) \ - _bitset_->buffer[i] = 0; \ -\ - _bitset_->buffer[end_index] &= ~end_mask; \ - } \ -\ - _bitset_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_bitset_, delete); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _flip)(struct SNAME * _bitset_, size_t bit_index) \ - { \ - if (!CMC_(PFX, _impl_resize)(_bitset_, bit_index + 1, false)) \ - return false; \ -\ - /* How many bits in a word */ \ - const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ -\ - size_t i = cmc_bidx_to_widx(bit_index); \ -\ - _bitset_->buffer[i] ^= ((cmc_bitset_word)1) << (bit_index % bits); \ -\ - _bitset_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_bitset_, update); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _flip_range)(struct SNAME * _bitset_, size_t from, size_t to) \ - { \ - if (to < from) \ - { \ - _bitset_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ -\ - if (!CMC_(PFX, _impl_resize)(_bitset_, to + 1, false)) \ - return false; \ -\ - size_t start_index = cmc_bidx_to_widx(from); \ - size_t end_index = cmc_bidx_to_widx(to); \ -\ - /* How many bits in a word */ \ - const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ -\ - /* 1111 ... 1111 */ \ - const cmc_bitset_word ones = ~((cmc_bitset_word)0); \ -\ - cmc_bitset_word shift_start = from % bits; \ - cmc_bitset_word shift_end = (cmc_bitset_word)(-(to + 1)) % bits; \ -\ - cmc_bitset_word start_mask = ones << shift_start; \ - cmc_bitset_word end_mask = ones >> shift_end; \ -\ - if (start_index == end_index) \ - { \ - _bitset_->buffer[end_index] ^= (start_mask & end_mask); \ - } \ - else \ - { \ - _bitset_->buffer[start_index] ^= start_mask; \ -\ - for (size_t i = start_index + 1; i < end_index; i++) \ - _bitset_->buffer[i] ^= ones; \ -\ - _bitset_->buffer[end_index] ^= end_mask; \ - } \ -\ - _bitset_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_bitset_, update); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _put)(struct SNAME * _bitset_, size_t bit_index, bool state) \ - { \ - if (state) \ - return CMC_(PFX, _set)(_bitset_, bit_index); \ - else \ - return CMC_(PFX, _clear)(_bitset_, bit_index); \ - } \ -\ - bool CMC_(PFX, _put_range)(struct SNAME * _bitset_, size_t from, size_t to, bool state) \ - { \ - if (state) \ - return CMC_(PFX, _set_range)(_bitset_, from, to); \ - else \ - return CMC_(PFX, _clear_range)(_bitset_, from, to); \ - } \ -\ - bool CMC_(PFX, _set_all)(struct SNAME * _bitset_) \ - { \ - for (size_t i = 0; i < _bitset_->capacity; i++) \ - _bitset_->buffer[i] = ~((cmc_bitset_word)0); \ -\ - _bitset_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_bitset_, create); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _clear_all)(struct SNAME * _bitset_) \ - { \ - for (size_t i = 0; i < _bitset_->capacity; i++) \ - _bitset_->buffer[i] = 0; \ -\ - _bitset_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_bitset_, delete); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _flip_all)(struct SNAME * _bitset_) \ - { \ - for (size_t i = 0; i < _bitset_->capacity; i++) \ - _bitset_->buffer[i] ^= ~((cmc_bitset_word)0); \ -\ - _bitset_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_bitset_, create); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _get)(struct SNAME * _bitset_, size_t bit_index) \ - { \ - /* How many bits in a word */ \ - const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \ -\ - cmc_bitset_word w = _bitset_->buffer[cmc_bidx_to_widx(bit_index)]; \ -\ - return w & ((cmc_bitset_word)1 << (bit_index % bits)); \ - } \ -\ - bool CMC_(PFX, _resize)(struct SNAME * _bitset_, size_t n_bits) \ - { \ - return CMC_(PFX, _impl_resize)(_bitset_, n_bits, true); \ - } \ -\ - /* When do_resize is false, then we just want to assure that the bitset */ \ - /* can accommodate n_bits */ \ - bool CMC_(PFX, _impl_resize)(struct SNAME * _bitset_, size_t n_bits, bool do_resize) \ - { \ - if (n_bits == 0) \ - { \ - _bitset_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ -\ - /* -1 because n_bits is 1-based and we need to pass a 0-based index */ \ - /* +1 to have a 1-based result */ \ - size_t words = cmc_bidx_to_widx(n_bits - 1) + 1; \ -\ - /* Be sure we are not always shrinking when we just want to make */ \ - /* sure that we have enough size for n_bits */ \ - if (!do_resize && words <= _bitset_->capacity) \ - return true; \ -\ - cmc_bitset_word *new_buffer = realloc(_bitset_->buffer, words * sizeof(cmc_bitset_word)); \ -\ - if (!new_buffer) \ - { \ - _bitset_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ -\ - _bitset_->buffer = new_buffer; \ -\ - /* Make new bits be all zeroes */ \ - if (_bitset_->capacity < words) \ - memset(_bitset_->buffer + _bitset_->capacity, 0, (words - _bitset_->capacity) * sizeof(cmc_bitset_word)); \ -\ - _bitset_->capacity = words; \ -\ - CMC_CALLBACKS_CALL(_bitset_, resize); \ -\ - _bitset_->flag = CMC_FLAG_OK; \ -\ - return true; \ - } - -#endif /* CMC_CMC_BITSET_H */ diff --git a/src/cmc_deque.h b/src/cmc_deque.h deleted file mode 100644 index e3a14d6..0000000 --- a/src/cmc_deque.h +++ /dev/null @@ -1,552 +0,0 @@ -/** - * Copyright (c) 2019 Leonardo Vencovsky - * - * This file is part of the C Macro Collections Libray. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * cmc_deque.h - * - * Creation Date: 20/03/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -/** - * Deque - * - * A Deque (double-ended queue) is a linear data structure that is able to add - * or remove elements from both ends. It can also be thought of a double-ended - * stack since you can push and pop elements from two ends. The Deque can also - * be used as a Queue. - * - * There is no random access for a Deque. The only elements accessible are the - * front element and the back. - * - * Implementation - * - * This implementation uses a circular buffer (ring buffer or cyclic buffer) in - * order to operate on O(1) for push and pop on either ends (only case where it - * takes longer than O(1) is when the buffer is reallocated). If it was - * implemented as a regular array, adding or removing elements from the front - * would take O(N) due to the need to shift all elements in the deque. - */ - -#ifndef CMC_CMC_DEQUE_H -#define CMC_CMC_DEQUE_H - -/* ------------------------------------------------------------------------- - * Core functionalities of the C Macro Collections Library - * ------------------------------------------------------------------------- */ -#include "cor_core.h" - -/** - * Core Deque implementation - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_CMC_DEQUE_CORE(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_CMC_DEQUE_CORE_, ACCESS), CMC_(_, FILE))(PARAMS) - -/* PRIVATE or PUBLIC solver */ -#define CMC_CMC_DEQUE_CORE_PUBLIC_HEADER(PARAMS) \ - CMC_CMC_DEQUE_CORE_STRUCT(PARAMS) \ - CMC_CMC_DEQUE_CORE_HEADER(PARAMS) - -#define CMC_CMC_DEQUE_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_DEQUE_CORE_SOURCE(PARAMS) - -#define CMC_CMC_DEQUE_CORE_PRIVATE_HEADER(PARAMS) \ - struct CMC_PARAM_SNAME(PARAMS); \ - CMC_CMC_DEQUE_CORE_HEADER(PARAMS) - -#define CMC_CMC_DEQUE_CORE_PRIVATE_SOURCE(PARAMS) \ - CMC_CMC_DEQUE_CORE_STRUCT(PARAMS) \ - CMC_CMC_DEQUE_CORE_SOURCE(PARAMS) - -/* Lowest level API */ -#define CMC_CMC_DEQUE_CORE_STRUCT(PARAMS) \ - CMC_CMC_DEQUE_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_CMC_DEQUE_CORE_HEADER(PARAMS) \ - CMC_CMC_DEQUE_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_CMC_DEQUE_CORE_SOURCE(PARAMS) \ - CMC_CMC_DEQUE_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -/* ------------------------------------------------------------------------- - * Struct - * ------------------------------------------------------------------------- */ -#define CMC_CMC_DEQUE_CORE_STRUCT_(PFX, SNAME, V) \ -\ - /* Deque Structure */ \ - struct SNAME \ - { \ - /* Dynamic circular array of elements */ \ - V *buffer; \ -\ - /* Current circular array capacity */ \ - size_t capacity; \ -\ - /* Current amount of elements */ \ - size_t count; \ -\ - /* Index representing the front of the deque */ \ - size_t front; \ -\ - /* Index representing the back of the deque */ \ - size_t back; \ -\ - /* Flags indicating errors or success */ \ - int flag; \ -\ - struct CMC_DEF_FVAL(SNAME) * f_val; \ -\ - /* Custom allocation functions */ \ - struct CMC_ALLOC_NODE_NAME *alloc; \ -\ - /* Custom callback functions */ \ - CMC_CALLBACKS_DECL; \ - }; - -/* ------------------------------------------------------------------------- - * Header - * ------------------------------------------------------------------------- */ -#define CMC_CMC_DEQUE_CORE_HEADER_(PFX, SNAME, V) \ -\ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(V); \ -\ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(V); \ -\ - /* To string function */ \ - CMC_DEF_FTAB_STR(V); \ -\ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(V); \ -\ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(V); \ -\ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(V); \ - }; \ -\ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks); \ - void CMC_(PFX, _clear)(struct SNAME * _deque_); \ - void CMC_(PFX, _free)(struct SNAME * _deque_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _deque_, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _push_front)(struct SNAME * _deque_, V value); \ - bool CMC_(PFX, _push_back)(struct SNAME * _deque_, V value); \ - bool CMC_(PFX, _pop_front)(struct SNAME * _deque_); \ - bool CMC_(PFX, _pop_back)(struct SNAME * _deque_); \ - /* Element Access */ \ - V CMC_(PFX, _front)(struct SNAME * _deque_); \ - V CMC_(PFX, _back)(struct SNAME * _deque_); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _deque_, V value); \ - bool CMC_(PFX, _empty)(struct SNAME * _deque_); \ - bool CMC_(PFX, _full)(struct SNAME * _deque_); \ - size_t CMC_(PFX, _count)(struct SNAME * _deque_); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _deque_); \ - int CMC_(PFX, _flag)(struct SNAME * _deque_); \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _deque_, size_t capacity); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _deque_); \ - bool CMC_(PFX, _equals)(struct SNAME * _deque1_, struct SNAME * _deque2_); - -/* ------------------------------------------------------------------------- - * Source - * ------------------------------------------------------------------------- */ -#define CMC_CMC_DEQUE_CORE_SOURCE_(PFX, SNAME, V) \ -\ - /* Implementation Detail Functions */ \ - /* None */ \ -\ - struct SNAME *CMC_(PFX, _new)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - return CMC_(PFX, _new_custom)(capacity, f_val, NULL, NULL); \ - } \ -\ - struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - if (capacity < 1) \ - return NULL; \ -\ - if (!f_val) \ - return NULL; \ -\ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ -\ - struct SNAME *_deque_ = alloc->malloc(sizeof(struct SNAME)); \ -\ - if (!_deque_) \ - return NULL; \ -\ - _deque_->buffer = alloc->calloc(capacity, sizeof(V)); \ -\ - if (!_deque_->buffer) \ - { \ - alloc->free(_deque_); \ - return NULL; \ - } \ -\ - _deque_->capacity = capacity; \ - _deque_->count = 0; \ - _deque_->front = 0; \ - _deque_->back = 0; \ - _deque_->flag = CMC_FLAG_OK; \ - _deque_->f_val = f_val; \ - _deque_->alloc = alloc; \ - CMC_CALLBACKS_ASSIGN(_deque_, callbacks); \ -\ - return _deque_; \ - } \ -\ - void CMC_(PFX, _clear)(struct SNAME * _deque_) \ - { \ - if (_deque_->f_val->free) \ - { \ - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ - { \ - _deque_->f_val->free(_deque_->buffer[i]); \ -\ - i = (i + 1) % _deque_->capacity; \ - } \ - } \ -\ - memset(_deque_->buffer, 0, sizeof(V) * _deque_->capacity); \ -\ - _deque_->count = 0; \ - _deque_->front = 0; \ - _deque_->back = 0; \ -\ - _deque_->flag = CMC_FLAG_OK; \ - } \ -\ - void CMC_(PFX, _free)(struct SNAME * _deque_) \ - { \ - if (_deque_->f_val->free) \ - { \ - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ - { \ - _deque_->f_val->free(_deque_->buffer[i]); \ -\ - i = (i + 1) % _deque_->capacity; \ - } \ - } \ -\ - _deque_->alloc->free(_deque_->buffer); \ - _deque_->alloc->free(_deque_); \ - } \ -\ - void CMC_(PFX, _customize)(struct SNAME * _deque_, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - if (!alloc) \ - _deque_->alloc = &cmc_alloc_node_default; \ - else \ - _deque_->alloc = alloc; \ -\ - CMC_CALLBACKS_ASSIGN(_deque_, callbacks); \ -\ - _deque_->flag = CMC_FLAG_OK; \ - } \ -\ - bool CMC_(PFX, _push_front)(struct SNAME * _deque_, V value) \ - { \ - if (CMC_(PFX, _full)(_deque_)) \ - { \ - if (!CMC_(PFX, _resize)(_deque_, _deque_->capacity * 2)) \ - return false; \ - } \ -\ - _deque_->front = (_deque_->front == 0) ? _deque_->capacity - 1 : _deque_->front - 1; \ -\ - _deque_->buffer[_deque_->front] = value; \ -\ - _deque_->count++; \ - _deque_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_deque_, create); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _push_back)(struct SNAME * _deque_, V value) \ - { \ - if (CMC_(PFX, _full)(_deque_)) \ - { \ - if (!CMC_(PFX, _resize)(_deque_, _deque_->capacity * 2)) \ - return false; \ - } \ -\ - _deque_->buffer[_deque_->back] = value; \ -\ - _deque_->back = (_deque_->back == _deque_->capacity - 1) ? 0 : _deque_->back + 1; \ -\ - _deque_->count++; \ - _deque_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_deque_, create); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _pop_front)(struct SNAME * _deque_) \ - { \ - if (CMC_(PFX, _empty)(_deque_)) \ - { \ - _deque_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - _deque_->buffer[_deque_->front] = (V){ 0 }; \ -\ - _deque_->front = (_deque_->front == _deque_->capacity - 1) ? 0 : _deque_->front + 1; \ -\ - _deque_->count--; \ - _deque_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_deque_, delete); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _pop_back)(struct SNAME * _deque_) \ - { \ - if (CMC_(PFX, _empty)(_deque_)) \ - { \ - _deque_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - _deque_->back = (_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1; \ -\ - _deque_->buffer[_deque_->back] = (V){ 0 }; \ -\ - _deque_->count--; \ - _deque_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_deque_, delete); \ -\ - return true; \ - } \ -\ - V CMC_(PFX, _front)(struct SNAME * _deque_) \ - { \ - if (CMC_(PFX, _empty)(_deque_)) \ - { \ - _deque_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ -\ - _deque_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_deque_, read); \ -\ - return _deque_->buffer[_deque_->front]; \ - } \ -\ - V CMC_(PFX, _back)(struct SNAME * _deque_) \ - { \ - if (CMC_(PFX, _empty)(_deque_)) \ - { \ - _deque_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ -\ - _deque_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_deque_, read); \ -\ - return _deque_->buffer[(_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1]; \ - } \ -\ - bool CMC_(PFX, _contains)(struct SNAME * _deque_, V value) \ - { \ - _deque_->flag = CMC_FLAG_OK; \ -\ - bool result = false; \ -\ - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ - { \ - if (_deque_->f_val->cmp(_deque_->buffer[i], value) == 0) \ - { \ - result = true; \ - break; \ - } \ -\ - i = (i + 1) % _deque_->capacity; \ - } \ -\ - CMC_CALLBACKS_CALL(_deque_, read); \ -\ - return result; \ - } \ -\ - bool CMC_(PFX, _empty)(struct SNAME * _deque_) \ - { \ - return _deque_->count == 0; \ - } \ -\ - bool CMC_(PFX, _full)(struct SNAME * _deque_) \ - { \ - return _deque_->count >= _deque_->capacity; \ - } \ -\ - size_t CMC_(PFX, _count)(struct SNAME * _deque_) \ - { \ - return _deque_->count; \ - } \ -\ - size_t CMC_(PFX, _capacity)(struct SNAME * _deque_) \ - { \ - return _deque_->capacity; \ - } \ -\ - int CMC_(PFX, _flag)(struct SNAME * _deque_) \ - { \ - return _deque_->flag; \ - } \ -\ - bool CMC_(PFX, _resize)(struct SNAME * _deque_, size_t capacity) \ - { \ - _deque_->flag = CMC_FLAG_OK; \ -\ - if (_deque_->capacity == capacity) \ - goto success; \ -\ - if (capacity < _deque_->count) \ - { \ - _deque_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ -\ - V *new_buffer = _deque_->alloc->malloc(sizeof(V) * capacity); \ -\ - if (!new_buffer) \ - { \ - _deque_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ -\ - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ - { \ - new_buffer[j] = _deque_->buffer[i]; \ -\ - i = (i + 1) % _deque_->capacity; \ - } \ -\ - _deque_->alloc->free(_deque_->buffer); \ -\ - _deque_->buffer = new_buffer; \ - _deque_->capacity = capacity; \ - _deque_->front = 0; \ - _deque_->back = _deque_->count; \ -\ - success: \ -\ - CMC_CALLBACKS_CALL(_deque_, resize); \ -\ - return true; \ - } \ -\ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _deque_) \ - { \ - struct SNAME *result = CMC_(PFX, _new_custom)(_deque_->capacity, _deque_->f_val, _deque_->alloc, NULL); \ -\ - if (!result) \ - { \ - _deque_->flag = CMC_FLAG_ERROR; \ - return NULL; \ - } \ -\ - CMC_CALLBACKS_ASSIGN(result, _deque_->callbacks); \ -\ - if (_deque_->f_val->cpy) \ - { \ - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ - { \ - result->buffer[j] = _deque_->f_val->cpy(_deque_->buffer[i]); \ -\ - i = (i + 1) % _deque_->capacity; \ - } \ - } \ - else \ - { \ - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ - { \ - result->buffer[j] = _deque_->buffer[i]; \ -\ - i = (i + 1) % _deque_->capacity; \ - } \ - } \ -\ - result->count = _deque_->count; \ - result->front = 0; \ - result->back = _deque_->count; \ -\ - _deque_->flag = CMC_FLAG_OK; \ -\ - return result; \ - } \ -\ - bool CMC_(PFX, _equals)(struct SNAME * _deque1_, struct SNAME * _deque2_) \ - { \ - _deque1_->flag = CMC_FLAG_OK; \ - _deque2_->flag = CMC_FLAG_OK; \ -\ - if (_deque1_->count != _deque2_->count) \ - return false; \ -\ - size_t i, j, k; \ - for (i = _deque1_->front, j = _deque2_->front, k = 0; k < _deque1_->count; k++) \ - { \ - if (_deque1_->f_val->cmp(_deque1_->buffer[i], _deque2_->buffer[j]) != 0) \ - return false; \ -\ - i = (i + 1) % _deque1_->capacity; \ - j = (j + 1) % _deque2_->capacity; \ - } \ -\ - return true; \ - } - -#endif /* CMC_CMC_DEQUE_H */ diff --git a/src/cmc_hashbidimap.h b/src/cmc_hashbidimap.h deleted file mode 100644 index dad8539..0000000 --- a/src/cmc_hashbidimap.h +++ /dev/null @@ -1,1376 +0,0 @@ -/** - * Copyright (c) 2019 Leonardo Vencovsky - * - * This file is part of the C Macro Collections Libray. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * cmc_hashbidimap.h - * - * Creation Date: 26/09/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -/** - * HashBidiMap - * - * A bidirectional map is a map that allows you to create a bijection in both - * directions between two sets of elements (K <-> V). It is possible to retrieve - * the value using a key or retrieve a key using a value. The naming is simply - * used to differentiate between one set of elements and the other set of - * elements. - * - * Implementation - * - * This implementation uses two arrays of pointers to an entry containing both - * the key and the value. - */ - -#ifndef CMC_CMC_HASHBIDIMAP_H -#define CMC_CMC_HASHBIDIMAP_H - -/* ------------------------------------------------------------------------- - * Core functionalities of the C Macro Collections Library - * ------------------------------------------------------------------------- */ -#include "cor_core.h" - -/* ------------------------------------------------------------------------- - * Hashtable Implementation - * ------------------------------------------------------------------------- */ -#include "cor_hashtable.h" - -/** - * Core HashBidiMap implementation - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_CMC_HASHBIDIMAP_CORE(ACCESS, FILE, PARAMS) \ - CMC_(CMC_(CMC_CMC_HASHBIDIMAP_CORE_, ACCESS), CMC_(_, FILE))(PARAMS) - -/* PRIVATE or PUBLIC solver */ -#define CMC_CMC_HASHBIDIMAP_CORE_PUBLIC_HEADER(PARAMS) \ - CMC_CMC_HASHBIDIMAP_CORE_STRUCT(PARAMS) \ - CMC_CMC_HASHBIDIMAP_CORE_HEADER(PARAMS) - -#define CMC_CMC_HASHBIDIMAP_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_HASHBIDIMAP_CORE_SOURCE(PARAMS) - -#define CMC_CMC_HASHBIDIMAP_CORE_PRIVATE_HEADER(PARAMS) \ - struct CMC_PARAM_SNAME(PARAMS); \ - struct CMC_DEF_ENTRY(CMC_PARAM_SNAME(PARAMS)); \ - CMC_CMC_HASHBIDIMAP_CORE_HEADER(PARAMS) - -#define CMC_CMC_HASHBIDIMAP_CORE_PRIVATE_SOURCE(PARAMS) \ - CMC_CMC_HASHBIDIMAP_CORE_STRUCT(PARAMS) \ - CMC_CMC_HASHBIDIMAP_CORE_SOURCE(PARAMS) - -/* Lowest level API */ -#define CMC_CMC_HASHBIDIMAP_CORE_STRUCT(PARAMS) \ - CMC_CMC_HASHBIDIMAP_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_CMC_HASHBIDIMAP_CORE_HEADER(PARAMS) \ - CMC_CMC_HASHBIDIMAP_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_CMC_HASHBIDIMAP_CORE_SOURCE(PARAMS) \ - CMC_CMC_HASHBIDIMAP_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -/* ------------------------------------------------------------------------- - * Struct - * ------------------------------------------------------------------------- */ -#define CMC_CMC_HASHBIDIMAP_CORE_STRUCT_(PFX, SNAME, K, V) \ -\ - /* HashBidiMap Structure */ \ - struct SNAME \ - { \ - /* Array 0 is K -> V and array 1 is V -> K */ \ - struct CMC_DEF_ENTRY(SNAME) * (*buffer)[2]; \ -\ - /* Current arrays capacity */ \ - size_t capacity; \ -\ - /* Current amount of keys */ \ - size_t count; \ -\ - /* Load factor in range (0.0, 1.0) */ \ - double load; \ -\ - /* Flags indicating errors or success */ \ - int flag; \ -\ - /* Key function table */ \ - struct CMC_DEF_FKEY(SNAME) * f_key; \ -\ - /* Value function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ -\ - /* Custom allocation functions */ \ - struct CMC_ALLOC_NODE_NAME *alloc; \ -\ - /* Custom callback functions */ \ - CMC_CALLBACKS_DECL; \ -\ - /* Methods */ \ - /* Returns an iterator to the start of the hashbidimap */ \ - struct CMC_DEF_ITER(SNAME) (*it_start)(struct SNAME *); \ -\ - /* Returns an iterator to the end of the hashbidimap */ \ - struct CMC_DEF_ITER(SNAME) (*it_end)(struct SNAME *); \ - }; \ -\ - /* HashBidiMap Entry */ \ - struct CMC_DEF_ENTRY(SNAME) \ - { \ - /* Entry Key */ \ - K key; \ -\ - /* Entry Value */ \ - V value; \ -\ - /* The distance of this node to its original position */ \ - /* dist[0] is relative to K -> V */ \ - /* dist[1] is relative to V -> K */ \ - size_t dist[2]; \ -\ - /* References to this node in the hashbidimap buffer. Used to */ \ - /* prevent searching for this node twice for update() and */ \ - /* remove(). Increases memory overhead but reduces execution time */ \ - /* ref[0] is relative to K -> V */ \ - /* ref[1] is relative to V -> K */ \ - struct CMC_DEF_ENTRY(SNAME) * *ref[2]; \ - }; - -/* ------------------------------------------------------------------------- - * Header - * ------------------------------------------------------------------------- */ -#define CMC_CMC_HASHBIDIMAP_CORE_HEADER_(PFX, SNAME, K, V) \ -\ - /* Key struct function table */ \ - struct CMC_DEF_FKEY(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(K); \ -\ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(K); \ -\ - /* To string function */ \ - CMC_DEF_FTAB_STR(K); \ -\ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(K); \ -\ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(K); \ -\ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(K); \ - }; \ -\ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(V); \ -\ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(V); \ -\ - /* To string function */ \ - CMC_DEF_FTAB_STR(V); \ -\ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(V); \ -\ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(V); \ -\ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(V); \ - }; \ -\ - /* HashBidiMap Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target hashbidimap */ \ - struct SNAME *target; \ -\ - /* Cursor's position (index) */ \ - size_t cursor; \ -\ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ -\ - /* The index of the first element */ \ - size_t first; \ -\ - /* The index of the last element */ \ - size_t last; \ -\ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ -\ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ -\ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \ - struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \ - struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks); \ - void CMC_(PFX, _clear)(struct SNAME * _map_); \ - void CMC_(PFX, _free)(struct SNAME * _map_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _map_, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value); \ - bool CMC_(PFX, _update_key)(struct SNAME * _map_, V val, K new_key); \ - bool CMC_(PFX, _update_val)(struct SNAME * _map_, K key, V new_val); \ - bool CMC_(PFX, _remove_by_key)(struct SNAME * _map_, K key, K * out_key, V * out_val); \ - bool CMC_(PFX, _remove_by_val)(struct SNAME * _map_, V val, K * out_key, V * out_val); \ - /* Element Access */ \ - K CMC_(PFX, _get_key)(struct SNAME * _map_, V val); \ - V CMC_(PFX, _get_val)(struct SNAME * _map_, K key); \ - /* Collection State */ \ - bool CMC_(PFX, _contains_key)(struct SNAME * _map_, K key); \ - bool CMC_(PFX, _contains_val)(struct SNAME * _map_, V val); \ - bool CMC_(PFX, _empty)(struct SNAME * _map_); \ - bool CMC_(PFX, _full)(struct SNAME * _map_); \ - size_t CMC_(PFX, _count)(struct SNAME * _map_); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _map_); \ - double CMC_(PFX, _load)(struct SNAME * _map_); \ - int CMC_(PFX, _flag)(struct SNAME * _map_); \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_); \ - bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_); \ -\ - /* Iterator Functions */ \ - /* Iterator Allocation and Deallocation */ \ - struct CMC_DEF_ITER(SNAME) * CMC_(PFX, _iter_new)(struct SNAME * target); \ - void CMC_(PFX, _iter_free)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Initialization */ \ - void CMC_(PFX, _iter_init)(struct CMC_DEF_ITER(SNAME) * iter, struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - void CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - void CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ - /* Iterator Access */ \ - K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter); \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); - -/* ------------------------------------------------------------------------- - * Source - * ------------------------------------------------------------------------- */ -#define CMC_CMC_HASHBIDIMAP_CORE_SOURCE_(PFX, SNAME, K, V) \ -\ - /* Implementation Detail Functions */ \ - static struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_new_entry)(struct SNAME * _map_, K key, V value); \ - static struct CMC_DEF_ENTRY(SNAME) * *CMC_(PFX, _impl_get_entry_by_key)(struct SNAME * _map_, K key); \ - static struct CMC_DEF_ENTRY(SNAME) * *CMC_(PFX, _impl_get_entry_by_val)(struct SNAME * _map_, V val); \ - static struct CMC_DEF_ENTRY(SNAME) * \ - *CMC_(PFX, _impl_add_entry_to_key)(struct SNAME * _map_, struct CMC_DEF_ENTRY(SNAME) * entry); \ - static struct CMC_DEF_ENTRY(SNAME) * \ - *CMC_(PFX, _impl_add_entry_to_val)(struct SNAME * _map_, struct CMC_DEF_ENTRY(SNAME) * entry); \ - static size_t CMC_(PFX, _impl_calculate_size)(size_t required); \ - static struct CMC_DEF_ITER(SNAME) CMC_(PFX, _impl_it_start)(struct SNAME * _map_); \ - static struct CMC_DEF_ITER(SNAME) CMC_(PFX, _impl_it_end)(struct SNAME * _map_); \ -\ - struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \ - struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - return CMC_(PFX, _new_custom)(capacity, load, f_key, f_val, NULL, NULL); \ - } \ -\ - struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \ - struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - if (capacity == 0 || load <= 0 || load >= 1) \ - return NULL; \ -\ - /* Prevent integer overflow */ \ - if (capacity >= UINTMAX_MAX * load) \ - return NULL; \ -\ - if (!f_key || !f_val) \ - return NULL; \ -\ - size_t real_capacity = CMC_(PFX, _impl_calculate_size)(capacity / load); \ -\ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ -\ - struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \ -\ - if (!_map_) \ - return NULL; \ -\ - _map_->buffer = alloc->calloc(real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME) *[2])); \ -\ - if (!_map_->buffer) \ - { \ - alloc->free(_map_->buffer); \ - alloc->free(_map_); \ - return NULL; \ - } \ -\ - _map_->count = 0; \ - _map_->capacity = real_capacity; \ - _map_->load = load; \ - _map_->flag = CMC_FLAG_OK; \ - _map_->f_key = f_key; \ - _map_->f_val = f_val; \ - _map_->flag = CMC_FLAG_OK; \ - _map_->alloc = alloc; \ - CMC_CALLBACKS_ASSIGN(_map_, callbacks); \ - _map_->it_start = CMC_(PFX, _impl_it_start); \ - _map_->it_end = CMC_(PFX, _impl_it_end); \ -\ - return _map_; \ - } \ -\ - void CMC_(PFX, _clear)(struct SNAME * _map_) \ - { \ - for (size_t i = 0; i < _map_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = _map_->buffer[i][0]; \ -\ - if (entry && entry != CMC_ENTRY_DELETED) \ - { \ - if (_map_->f_key->free) \ - _map_->f_key->free(entry->key); \ - if (_map_->f_val->free) \ - _map_->f_val->free(entry->value); \ -\ - _map_->alloc->free(entry); \ - } \ -\ - _map_->buffer[i][0] = NULL; \ - _map_->buffer[i][1] = NULL; \ - } \ -\ - _map_->count = 0; \ - _map_->flag = CMC_FLAG_OK; \ - } \ -\ - void CMC_(PFX, _free)(struct SNAME * _map_) \ - { \ - CMC_(PFX, _clear)(_map_); \ -\ - _map_->alloc->free(_map_->buffer); \ - _map_->alloc->free(_map_); \ - } \ -\ - void CMC_(PFX, _customize)(struct SNAME * _map_, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - if (!alloc) \ - _map_->alloc = &cmc_alloc_node_default; \ - else \ - _map_->alloc = alloc; \ -\ - CMC_CALLBACKS_ASSIGN(_map_, callbacks); \ -\ - _map_->flag = CMC_FLAG_OK; \ - } \ -\ - bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value) \ - { \ - if (CMC_(PFX, _full)(_map_)) \ - { \ - if (!CMC_(PFX, _resize)(_map_, _map_->capacity + 1)) \ - return false; \ - } \ -\ - if (CMC_(PFX, _impl_get_entry_by_key)(_map_, key) != NULL || \ - CMC_(PFX, _impl_get_entry_by_val)(_map_, value) != NULL) \ - { \ - _map_->flag = CMC_FLAG_DUPLICATE; \ - return false; \ - } \ -\ - struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_new_entry)(_map_, key, value); \ -\ - struct CMC_DEF_ENTRY(SNAME) **key_entry = CMC_(PFX, _impl_add_entry_to_key)(_map_, entry); \ - struct CMC_DEF_ENTRY(SNAME) **val_entry = CMC_(PFX, _impl_add_entry_to_val)(_map_, entry); \ -\ - if (!key_entry || !val_entry) \ - { \ - if (key_entry) \ - *key_entry = CMC_ENTRY_DELETED; \ - if (val_entry) \ - *val_entry = CMC_ENTRY_DELETED; \ -\ - _map_->alloc->free(entry); \ -\ - _map_->flag = CMC_FLAG_ERROR; \ -\ - return false; \ - } \ -\ - _map_->count++; \ - _map_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_map_, create); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _update_key)(struct SNAME * _map_, V val, K new_key) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - struct CMC_DEF_ENTRY(SNAME) * *key_entry, **val_entry; \ -\ - val_entry = CMC_(PFX, _impl_get_entry_by_val)(_map_, val); \ -\ - if (!val_entry) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return false; \ - } \ -\ - /* The mapping val -> new_key is already true */ \ - if (_map_->f_key->cmp(new_key, (*val_entry)->key) == 0) \ - goto success; \ -\ - if (CMC_(PFX, _impl_get_entry_by_key)(_map_, new_key) != NULL) \ - { \ - _map_->flag = CMC_FLAG_DUPLICATE; \ - return false; \ - } \ -\ - key_entry = (*val_entry)->ref[0]; \ -\ - if (!key_entry || *key_entry != *val_entry) \ - { \ - /* Should never happen */ \ - _map_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ -\ - /* Remove entry from key buffer and add it again with new key */ \ - struct CMC_DEF_ENTRY(SNAME) *to_add = *key_entry; \ - K tmp_key = to_add->key; \ - to_add->key = new_key; \ -\ - *key_entry = CMC_ENTRY_DELETED; \ -\ - if (!CMC_(PFX, _impl_add_entry_to_key)(_map_, to_add)) \ - { \ - /* Revert changes */ \ - to_add->key = tmp_key; \ - *key_entry = to_add; \ -\ - _map_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ -\ - success: \ -\ - _map_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_map_, update); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _update_val)(struct SNAME * _map_, K key, V new_val) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - struct CMC_DEF_ENTRY(SNAME) * *key_entry, **val_entry; \ -\ - key_entry = CMC_(PFX, _impl_get_entry_by_key)(_map_, key); \ -\ - if (!key_entry) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return false; \ - } \ -\ - /* The mapping key -> new_val is already true */ \ - if (_map_->f_val->cmp(new_val, (*key_entry)->value) == 0) \ - goto success; \ -\ - if (CMC_(PFX, _impl_get_entry_by_val)(_map_, new_val) != NULL) \ - { \ - _map_->flag = CMC_FLAG_DUPLICATE; \ - return false; \ - } \ -\ - val_entry = (*key_entry)->ref[1]; \ -\ - if (!val_entry || *val_entry != *key_entry) \ - { \ - /* Should never happen */ \ - _map_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ -\ - /* Remove entry from value buffer and add it again with new value */ \ - struct CMC_DEF_ENTRY(SNAME) *to_add = *val_entry; \ - V tmp_val = to_add->value; \ - to_add->value = new_val; \ -\ - *val_entry = CMC_ENTRY_DELETED; \ -\ - if (!CMC_(PFX, _impl_add_entry_to_val)(_map_, to_add)) \ - { \ - /* Revert changes */ \ - to_add->value = tmp_val; \ - *val_entry = to_add; \ -\ - _map_->flag = CMC_FLAG_ERROR; \ -\ - return false; \ - } \ -\ - success: \ -\ - _map_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_map_, update); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _remove_by_key)(struct SNAME * _map_, K key, K * out_key, V * out_val) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - struct CMC_DEF_ENTRY(SNAME) * *key_entry, **val_entry; \ -\ - key_entry = CMC_(PFX, _impl_get_entry_by_key)(_map_, key); \ -\ - if (!key_entry) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return false; \ - } \ -\ - val_entry = (*key_entry)->ref[1]; \ -\ - if (!val_entry || *val_entry != *key_entry) \ - { \ - /* Should never happen */ \ - _map_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ -\ - if (out_key) \ - *out_key = (*key_entry)->key; \ - if (out_val) \ - *out_val = (*key_entry)->value; \ -\ - _map_->alloc->free(*key_entry); \ -\ - *key_entry = CMC_ENTRY_DELETED; \ - *val_entry = CMC_ENTRY_DELETED; \ -\ - _map_->count--; \ - _map_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_map_, delete); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _remove_by_val)(struct SNAME * _map_, V val, K * out_key, V * out_val) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - struct CMC_DEF_ENTRY(SNAME) * *key_entry, **val_entry; \ -\ - val_entry = CMC_(PFX, _impl_get_entry_by_val)(_map_, val); \ -\ - if (!val_entry) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return false; \ - } \ -\ - key_entry = (*val_entry)->ref[0]; \ -\ - if (!key_entry || *key_entry != *val_entry) \ - { \ - /* Should never happen */ \ - _map_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ -\ - if (out_key) \ - *out_key = (*val_entry)->key; \ - if (out_val) \ - *out_val = (*val_entry)->value; \ -\ - _map_->alloc->free(*val_entry); \ -\ - *key_entry = CMC_ENTRY_DELETED; \ - *val_entry = CMC_ENTRY_DELETED; \ -\ - _map_->count--; \ - _map_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_map_, delete); \ -\ - return true; \ - } \ -\ - K CMC_(PFX, _get_key)(struct SNAME * _map_, V val) \ - { \ - struct CMC_DEF_ENTRY(SNAME) **entry = CMC_(PFX, _impl_get_entry_by_val)(_map_, val); \ -\ - if (!entry) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return (K){ 0 }; \ - } \ -\ - _map_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_map_, read); \ -\ - return (*entry)->key; \ - } \ -\ - V CMC_(PFX, _get_val)(struct SNAME * _map_, K key) \ - { \ - struct CMC_DEF_ENTRY(SNAME) **entry = CMC_(PFX, _impl_get_entry_by_key)(_map_, key); \ -\ - if (!entry) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return (V){ 0 }; \ - } \ -\ - _map_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_map_, read); \ -\ - return (*entry)->value; \ - } \ -\ - bool CMC_(PFX, _contains_key)(struct SNAME * _map_, K key) \ - { \ - _map_->flag = CMC_FLAG_OK; \ -\ - bool result = CMC_(PFX, _impl_get_entry_by_key)(_map_, key) != NULL; \ -\ - CMC_CALLBACKS_CALL(_map_, read); \ -\ - return result; \ - } \ -\ - bool CMC_(PFX, _contains_val)(struct SNAME * _map_, V val) \ - { \ - _map_->flag = CMC_FLAG_OK; \ -\ - bool result = CMC_(PFX, _impl_get_entry_by_val)(_map_, val) != NULL; \ -\ - CMC_CALLBACKS_CALL(_map_, read); \ -\ - return result; \ - } \ -\ - bool CMC_(PFX, _empty)(struct SNAME * _map_) \ - { \ - return _map_->count == 0; \ - } \ -\ - bool CMC_(PFX, _full)(struct SNAME * _map_) \ - { \ - return (double)_map_->capacity * _map_->load <= (double)_map_->count; \ - } \ -\ - size_t CMC_(PFX, _count)(struct SNAME * _map_) \ - { \ - return _map_->count; \ - } \ -\ - size_t CMC_(PFX, _capacity)(struct SNAME * _map_) \ - { \ - return _map_->capacity; \ - } \ -\ - double CMC_(PFX, _load)(struct SNAME * _map_) \ - { \ - return _map_->load; \ - } \ -\ - int CMC_(PFX, _flag)(struct SNAME * _map_) \ - { \ - return _map_->flag; \ - } \ -\ - bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity) \ - { \ - _map_->flag = CMC_FLAG_OK; \ -\ - if (_map_->capacity == capacity) \ - goto success; \ -\ - if (_map_->capacity > capacity / _map_->load) \ - goto success; \ -\ - /* Prevent integer overflow */ \ - if (capacity >= UINTMAX_MAX * _map_->load) \ - { \ - _map_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ -\ - /* Calculate required capacity based on the prime numbers */ \ - size_t new_cap = CMC_(PFX, _impl_calculate_size)(capacity); \ -\ - /* Not possible to shrink with current available prime numbers */ \ - if (new_cap < _map_->count / _map_->load) \ - { \ - _map_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ -\ - /* No callbacks since _new_map_ is just a temporary hashtable */ \ - struct SNAME *_new_map_ = \ - CMC_(PFX, _new_custom)(capacity, _map_->load, _map_->f_key, _map_->f_val, _map_->alloc, NULL); \ -\ - if (!_new_map_) \ - { \ - _map_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ -\ - for (size_t i = 0; i < _map_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[i][0]; \ -\ - if (scan && scan != CMC_ENTRY_DELETED) \ - { \ - struct CMC_DEF_ENTRY(SNAME) **e1 = CMC_(PFX, _impl_add_entry_to_key)(_new_map_, scan); \ - struct CMC_DEF_ENTRY(SNAME) **e2 = CMC_(PFX, _impl_add_entry_to_val)(_new_map_, scan); \ -\ - if (!e1 || !e2) \ - { \ - /* Prevent the map from freeing the data */ \ - _new_map_->f_key = &(struct CMC_DEF_FKEY(SNAME)){ NULL }; \ - _new_map_->f_val = &(struct CMC_DEF_FVAL(SNAME)){ NULL }; \ -\ - _map_->alloc->free(_new_map_->buffer); \ - _map_->alloc->free(_new_map_); \ -\ - _map_->flag = CMC_FLAG_ERROR; \ -\ - return false; \ - } \ -\ - _new_map_->count++; \ - } \ - } \ -\ - if (_map_->count != _new_map_->count) \ - { \ - /* Prevent the map from freeing the data */ \ - _new_map_->f_key = &(struct CMC_DEF_FKEY(SNAME)){ NULL }; \ - _new_map_->f_val = &(struct CMC_DEF_FVAL(SNAME)){ NULL }; \ -\ - _map_->alloc->free(_new_map_->buffer); \ - _map_->alloc->free(_new_map_); \ -\ - _map_->flag = CMC_FLAG_ERROR; \ -\ - return false; \ - } \ -\ - struct CMC_DEF_ENTRY(SNAME) * (*tmp_buff)[2] = _map_->buffer; \ -\ - _map_->buffer = _new_map_->buffer; \ - _map_->capacity = _new_map_->capacity; \ -\ - _map_->alloc->free(tmp_buff); \ - _map_->alloc->free(_new_map_); \ -\ - success: \ -\ - CMC_CALLBACKS_CALL(_map_, resize); \ -\ - return true; \ - } \ -\ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_) \ - { \ - /* TODO this function can be optimized */ \ - struct SNAME *result = CMC_(PFX, _new_custom)(_map_->capacity * _map_->load, _map_->load, _map_->f_key, \ - _map_->f_val, _map_->alloc, NULL); \ -\ - if (!result) \ - { \ - _map_->flag = CMC_FLAG_ERROR; \ - return NULL; \ - } \ -\ - CMC_CALLBACKS_ASSIGN(result, _map_->callbacks); \ -\ - for (size_t i = 0; i < _map_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[i][0]; \ -\ - if (scan && scan != CMC_ENTRY_DELETED) \ - { \ - K tmp_key; \ - V tmp_val; \ -\ - if (_map_->f_key->cpy) \ - tmp_key = _map_->f_key->cpy(scan->key); \ - else \ - tmp_key = scan->key; \ -\ - if (_map_->f_val->cpy) \ - tmp_val = _map_->f_val->cpy(scan->value); \ - else \ - tmp_val = scan->value; \ -\ - /* TODO treat the possible errors */ \ - struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_new_entry)(result, tmp_key, tmp_val); \ -\ - CMC_(PFX, _impl_add_entry_to_key)(result, entry); \ - CMC_(PFX, _impl_add_entry_to_val)(result, entry); \ -\ - result->count++; \ - } \ - } \ -\ - _map_->flag = CMC_FLAG_OK; \ -\ - return result; \ - } \ -\ - bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_) \ - { \ - _map1_->flag = CMC_FLAG_OK; \ - _map2_->flag = CMC_FLAG_OK; \ -\ - if (_map1_->count != _map2_->count) \ - return false; \ -\ - struct SNAME *_mapA_; \ - struct SNAME *_mapB_; \ -\ - if (_map1_->capacity < _map2_->capacity) \ - { \ - _mapA_ = _map1_; \ - _mapB_ = _map2_; \ - } \ - else \ - { \ - _mapA_ = _map2_; \ - _mapB_ = _map1_; \ - } \ -\ - for (size_t i = 0; i < _mapA_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *scan = _mapA_->buffer[i][0]; \ -\ - if (scan && scan != CMC_ENTRY_DELETED) \ - { \ - struct CMC_DEF_ENTRY(SNAME) **entry_B = CMC_(PFX, _impl_get_entry_by_key)(_mapB_, scan->key); \ -\ - if (!entry_B) \ - return false; \ -\ - if (_mapA_->f_val->cmp((*entry_B)->value, scan->value) != 0) \ - return false; \ - } \ - } \ -\ - return true; \ - } \ -\ - struct CMC_DEF_ITER(SNAME) * CMC_(PFX, _iter_new)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) *iter = target->alloc->malloc(sizeof(struct CMC_DEF_ITER(SNAME))); \ -\ - if (!iter) \ - return NULL; \ -\ - CMC_(PFX, _iter_init)(iter, target); \ -\ - return iter; \ - } \ -\ - void CMC_(PFX, _iter_free)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - iter->target->alloc->free(iter); \ - } \ -\ - void CMC_(PFX, _iter_init)(struct CMC_DEF_ITER(SNAME) * iter, struct SNAME * target) \ - { \ - memset(iter, 0, sizeof(struct CMC_DEF_ITER(SNAME))); \ -\ - iter->target = target; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(target); \ -\ - if (!CMC_(PFX, _empty)(target)) \ - { \ - for (size_t i = 0; i < target->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = target->buffer[i][0]; \ -\ - if (entry && entry != CMC_ENTRY_DELETED) \ - { \ - iter->first = i; \ - break; \ - } \ - } \ -\ - iter->cursor = iter->first; \ -\ - for (size_t i = target->capacity; i > 0; i--) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = target->buffer[i - 1][0]; \ -\ - if (entry && entry != CMC_ENTRY_DELETED) \ - { \ - iter->last = i - 1; \ - break; \ - } \ - } \ - } \ - } \ -\ - bool CMC_(PFX, _iter_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ -\ - bool CMC_(PFX, _iter_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ -\ - void CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->first; \ - iter->index = 0; \ - iter->start = true; \ - iter->end = false; \ - } \ - } \ -\ - void CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->last; \ - iter->index = iter->target->count - 1; \ - iter->start = false; \ - iter->end = true; \ - } \ - } \ -\ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - iter->start = CMC_(PFX, _empty)(iter->target); \ -\ - struct CMC_DEF_ENTRY(SNAME) *scan = iter->target->buffer[iter->cursor][0]; \ -\ - iter->index++; \ -\ - while (1) \ - { \ - iter->cursor++; \ - scan = iter->target->buffer[iter->cursor][0]; \ -\ - if (scan != NULL && scan != CMC_ENTRY_DELETED) \ - break; \ - } \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - struct CMC_DEF_ENTRY(SNAME) *scan = iter->target->buffer[iter->cursor][0]; \ -\ - iter->index--; \ -\ - while (1) \ - { \ - iter->cursor--; \ - scan = iter->target->buffer[iter->cursor][0]; \ -\ - if (scan != NULL && scan != CMC_ENTRY_DELETED) \ - break; \ - } \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->index + steps >= iter->target->count) \ - return false; \ -\ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_next)(iter); \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->index < steps) \ - return false; \ -\ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_prev)(iter); \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator was able to be positioned at */ \ - /* the given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ -\ - if (iter->index > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ - else if (iter->index < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ -\ - return true; \ - } \ -\ - K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->target->flag = CMC_FLAG_EMPTY; \ - return (K){ 0 }; \ - } \ -\ - return iter->target->buffer[iter->cursor][0]->key; \ - } \ -\ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->target->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ -\ - return iter->target->buffer[iter->cursor][0]->value; \ - } \ -\ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->index; \ - } \ -\ - static struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_new_entry)(struct SNAME * _map_, K key, V value) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = _map_->alloc->malloc(sizeof(struct CMC_DEF_ENTRY(SNAME))); \ -\ - if (!entry) \ - return NULL; \ -\ - entry->key = key; \ - entry->value = value; \ - entry->dist[0] = 0; \ - entry->dist[1] = 0; \ - entry->ref[0] = NULL; \ - entry->ref[1] = NULL; \ -\ - return entry; \ - } \ -\ - static struct CMC_DEF_ENTRY(SNAME) * *CMC_(PFX, _impl_get_entry_by_key)(struct SNAME * _map_, K key) \ - { \ - size_t hash = _map_->f_key->hash(key); \ - size_t pos = hash % _map_->capacity; \ -\ - struct CMC_DEF_ENTRY(SNAME) *target = _map_->buffer[pos][0]; \ -\ - while (target != NULL) \ - { \ - if (target != CMC_ENTRY_DELETED && _map_->f_key->cmp(target->key, key) == 0) \ - return &(_map_->buffer[pos % _map_->capacity][0]); \ -\ - pos++; \ - target = _map_->buffer[pos % _map_->capacity][0]; \ - } \ -\ - return NULL; \ - } \ -\ - static struct CMC_DEF_ENTRY(SNAME) * *CMC_(PFX, _impl_get_entry_by_val)(struct SNAME * _map_, V val) \ - { \ - size_t hash = _map_->f_val->hash(val); \ - size_t pos = hash % _map_->capacity; \ -\ - struct CMC_DEF_ENTRY(SNAME) *target = _map_->buffer[pos][1]; \ -\ - while (target != NULL) \ - { \ - if (target != CMC_ENTRY_DELETED && _map_->f_val->cmp(target->value, val) == 0) \ - return &(_map_->buffer[pos % _map_->capacity][1]); \ -\ - pos++; \ - target = _map_->buffer[pos % _map_->capacity][1]; \ - } \ -\ - return NULL; \ - } \ -\ - static struct CMC_DEF_ENTRY(SNAME) * \ - *CMC_(PFX, _impl_add_entry_to_key)(struct SNAME * _map_, struct CMC_DEF_ENTRY(SNAME) * entry) \ - { \ - struct CMC_DEF_ENTRY(SNAME) **to_return = NULL; \ -\ - size_t hash = _map_->f_key->hash(entry->key); \ - size_t original_pos = hash % _map_->capacity; \ - size_t pos = original_pos; \ -\ - struct CMC_DEF_ENTRY(SNAME) **scan = &(_map_->buffer[hash % _map_->capacity][0]); \ -\ - if (*scan == NULL) \ - { \ - *scan = entry; \ -\ - entry->ref[0] = scan; \ -\ - return scan; \ - } \ - else \ - { \ - while (true) \ - { \ - pos++; \ - scan = &(_map_->buffer[pos % _map_->capacity][0]); \ -\ - if (*scan == NULL || *scan == CMC_ENTRY_DELETED) \ - { \ - if (!to_return) \ - to_return = scan; \ -\ - *scan = entry; \ - entry->ref[0] = scan; \ - entry->dist[0] = pos - original_pos; \ -\ - return to_return; \ - } \ - else if ((*scan)->dist[0] < pos - original_pos) \ - { \ - if (!to_return) \ - to_return = scan; \ -\ - size_t tmp_dist = (*scan)->dist[0]; \ - entry->dist[0] = pos - original_pos; \ - original_pos = pos - tmp_dist; \ -\ - entry->ref[0] = scan; \ -\ - struct CMC_DEF_ENTRY(SNAME) *_tmp_ = *scan; \ - *scan = entry; \ - entry = _tmp_; \ - } \ - } \ - } \ -\ - return NULL; \ - } \ -\ - static struct CMC_DEF_ENTRY(SNAME) * \ - *CMC_(PFX, _impl_add_entry_to_val)(struct SNAME * _map_, struct CMC_DEF_ENTRY(SNAME) * entry) \ - { \ - struct CMC_DEF_ENTRY(SNAME) **to_return = NULL; \ -\ - size_t hash = _map_->f_val->hash(entry->value); \ - size_t original_pos = hash % _map_->capacity; \ - size_t pos = original_pos; \ -\ - struct CMC_DEF_ENTRY(SNAME) **scan = &(_map_->buffer[hash % _map_->capacity][1]); \ -\ - if (*scan == NULL) \ - { \ - *scan = entry; \ -\ - entry->ref[1] = scan; \ -\ - return scan; \ - } \ - else \ - { \ - while (true) \ - { \ - pos++; \ - scan = &(_map_->buffer[pos % _map_->capacity][1]); \ -\ - if (*scan == NULL || *scan == CMC_ENTRY_DELETED) \ - { \ - if (!to_return) \ - to_return = scan; \ -\ - *scan = entry; \ - entry->ref[1] = scan; \ - entry->dist[1] = pos - original_pos; \ -\ - return to_return; \ - } \ - else if ((*scan)->dist[1] < pos - original_pos) \ - { \ - if (!to_return) \ - to_return = scan; \ -\ - size_t tmp_dist = (*scan)->dist[1]; \ - entry->dist[1] = pos - original_pos; \ - original_pos = pos - tmp_dist; \ -\ - entry->ref[1] = scan; \ -\ - struct CMC_DEF_ENTRY(SNAME) *_tmp_ = *scan; \ - *scan = entry; \ - entry = _tmp_; \ - } \ - } \ - } \ -\ - return NULL; \ - } \ -\ - static size_t CMC_(PFX, _impl_calculate_size)(size_t required) \ - { \ - const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); \ -\ - if (cmc_hashtable_primes[count - 1] < required) \ - return required; \ -\ - size_t i = 0; \ - while (cmc_hashtable_primes[i] < required) \ - i++; \ -\ - return cmc_hashtable_primes[i]; \ - } \ -\ - static struct CMC_DEF_ITER(SNAME) CMC_(PFX, _impl_it_start)(struct SNAME * _map_) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - CMC_(PFX, _iter_init)(&iter, _map_); \ -\ - return iter; \ - } \ -\ - static struct CMC_DEF_ITER(SNAME) CMC_(PFX, _impl_it_end)(struct SNAME * _map_) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - CMC_(PFX, _iter_init)(&iter, _map_); \ - CMC_(PFX, _iter_to_end)(&iter); \ -\ - return iter; \ - } - -#endif /* CMC_CMC_HASHBIDIMAP_H */ diff --git a/src/cmc_hashmap.h b/src/cmc_hashmap.h deleted file mode 100644 index ff7ed26..0000000 --- a/src/cmc_hashmap.h +++ /dev/null @@ -1,849 +0,0 @@ -/** - * Copyright (c) 2019 Leonardo Vencovsky - * - * This file is part of the C Macro Collections Libray. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * cmc_hashmap.h - * - * Creation Date: 03/04/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -/** - * HashMap - * - * A HashMap is an implementation of a Map with unique keys, where every key is - * mapped to a value. The keys are not sorted. It is implemented as a flat - * hashtable with linear probing and robin hood hashing. - */ - -#ifndef CMC_CMC_HASHMAP_H -#define CMC_CMC_HASHMAP_H - -/* ------------------------------------------------------------------------- - * Core functionalities of the C Macro Collections Library - * ------------------------------------------------------------------------- */ -#include "cor_core.h" - -/* ------------------------------------------------------------------------- - * Hashtable Implementation - * ------------------------------------------------------------------------- */ -#include "cor_hashtable.h" - -/** - * Core HashMap implementation - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_CMC_HASHMAP_CORE(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_CMC_HASHMAP_CORE_, ACCESS), CMC_(_, FILE))(PARAMS) - -/* PRIVATE or PUBLIC solver */ -#define CMC_CMC_HASHMAP_CORE_PUBLIC_HEADER(PARAMS) \ - CMC_CMC_HASHMAP_CORE_STRUCT(PARAMS) \ - CMC_CMC_HASHMAP_CORE_HEADER(PARAMS) - -#define CMC_CMC_HASHMAP_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_HASHMAP_CORE_SOURCE(PARAMS) - -#define CMC_CMC_HASHMAP_CORE_PRIVATE_HEADER(PARAMS) \ - struct CMC_PARAM_SNAME(PARAMS); \ - struct CMC_DEF_ENTRY(CMC_PARAM_SNAME(PARAMS)); \ - CMC_CMC_HASHMAP_CORE_HEADER(PARAMS) - -#define CMC_CMC_HASHMAP_CORE_PRIVATE_SOURCE(PARAMS) \ - CMC_CMC_HASHMAP_CORE_STRUCT(PARAMS) \ - CMC_CMC_HASHMAP_CORE_SOURCE(PARAMS) - -/* Lowest level API */ -#define CMC_CMC_HASHMAP_CORE_STRUCT(PARAMS) \ - CMC_CMC_HASHMAP_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_CMC_HASHMAP_CORE_HEADER(PARAMS) \ - CMC_CMC_HASHMAP_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_CMC_HASHMAP_CORE_SOURCE(PARAMS) \ - CMC_CMC_HASHMAP_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -/* ------------------------------------------------------------------------- - * Struct - * ------------------------------------------------------------------------- */ -#define CMC_CMC_HASHMAP_CORE_STRUCT_(PFX, SNAME, K, V) \ -\ - /* HashMap Structure */ \ - struct SNAME \ - { \ - /* Array of Entries */ \ - struct CMC_DEF_ENTRY(SNAME) * buffer; \ -\ - /* Current array capacity */ \ - size_t capacity; \ -\ - /* Current amount of keys */ \ - size_t count; \ -\ - /* Load factor in range (0.0, 1.0) */ \ - double load; \ -\ - /* Flags indicating errors or success */ \ - int flag; \ -\ - /* Key function table */ \ - struct CMC_DEF_FKEY(SNAME) * f_key; \ -\ - /* Value function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ -\ - /* Custom allocation functions */ \ - struct CMC_ALLOC_NODE_NAME *alloc; \ -\ - /* Custom callback functions */ \ - CMC_CALLBACKS_DECL; \ - }; \ -\ - /* HashMap Entry */ \ - struct CMC_DEF_ENTRY(SNAME) \ - { \ - /* Entry Key */ \ - K key; \ -\ - /* Entry Value */ \ - V value; \ -\ - /* The distance of this node to its original position, used by */ \ - /* robin-hood hashing */ \ - size_t dist; \ -\ - /* The sate of this node (DELETED, EMPTY, FILLED) */ \ - enum cmc_entry_state state; \ - }; - -/* ------------------------------------------------------------------------- - * Header - * ------------------------------------------------------------------------- */ -#define CMC_CMC_HASHMAP_CORE_HEADER_(PFX, SNAME, K, V) \ -\ - /* Key struct function table */ \ - struct CMC_DEF_FKEY(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(K); \ -\ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(K); \ -\ - /* To string function */ \ - CMC_DEF_FTAB_STR(K); \ -\ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(K); \ -\ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(K); \ -\ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(K); \ - }; \ -\ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(V); \ -\ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(V); \ -\ - /* To string function */ \ - CMC_DEF_FTAB_STR(V); \ -\ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(V); \ -\ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(V); \ -\ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(V); \ - }; \ -\ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \ - struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \ - struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks); \ - void CMC_(PFX, _clear)(struct SNAME * _map_); \ - void CMC_(PFX, _free)(struct SNAME * _map_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _map_, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value); \ - bool CMC_(PFX, _update)(struct SNAME * _map_, K key, V new_value, V * old_value); \ - bool CMC_(PFX, _remove)(struct SNAME * _map_, K key, V * out_value); \ - /* Element Access */ \ - bool CMC_(PFX, _max)(struct SNAME * _map_, K * key, V * value); \ - bool CMC_(PFX, _min)(struct SNAME * _map_, K * key, V * value); \ - V CMC_(PFX, _get)(struct SNAME * _map_, K key); \ - V *CMC_(PFX, _get_ref)(struct SNAME * _map_, K key); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _map_, K key); \ - bool CMC_(PFX, _empty)(struct SNAME * _map_); \ - bool CMC_(PFX, _full)(struct SNAME * _map_); \ - size_t CMC_(PFX, _count)(struct SNAME * _map_); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _map_); \ - double CMC_(PFX, _load)(struct SNAME * _map_); \ - int CMC_(PFX, _flag)(struct SNAME * _map_); \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_); \ - bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_); - -/* ------------------------------------------------------------------------- - * Source - * ------------------------------------------------------------------------- */ -#define CMC_CMC_HASHMAP_CORE_SOURCE_(PFX, SNAME, K, V) \ -\ - /* Implementation Detail Functions */ \ - static struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_get_entry)(struct SNAME * _map_, K key); \ - static size_t CMC_(PFX, _impl_calculate_size)(size_t required); \ -\ - struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \ - struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - return CMC_(PFX, _new_custom)(capacity, load, f_key, f_val, NULL, NULL); \ - } \ -\ - struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \ - struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - if (capacity == 0 || load <= 0 || load >= 1) \ - return NULL; \ -\ - /* Prevent integer overflow */ \ - if (capacity >= UINTMAX_MAX * load) \ - return NULL; \ -\ - if (!f_key || !f_val) \ - return NULL; \ -\ - size_t real_capacity = CMC_(PFX, _impl_calculate_size)(capacity / load); \ -\ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ -\ - struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \ -\ - if (!_map_) \ - return NULL; \ -\ - _map_->buffer = alloc->calloc(real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME))); \ -\ - if (!_map_->buffer) \ - { \ - alloc->free(_map_); \ - return NULL; \ - } \ -\ - _map_->count = 0; \ - _map_->capacity = real_capacity; \ - _map_->load = load; \ - _map_->flag = CMC_FLAG_OK; \ - _map_->f_key = f_key; \ - _map_->f_val = f_val; \ - _map_->alloc = alloc; \ - CMC_CALLBACKS_ASSIGN(_map_, callbacks); \ -\ - return _map_; \ - } \ -\ - void CMC_(PFX, _clear)(struct SNAME * _map_) \ - { \ - if (_map_->f_key->free || _map_->f_val->free) \ - { \ - for (size_t i = 0; i < _map_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = &(_map_->buffer[i]); \ -\ - if (entry->state == CMC_ES_FILLED) \ - { \ - if (_map_->f_key->free) \ - _map_->f_key->free(entry->key); \ - if (_map_->f_val->free) \ - _map_->f_val->free(entry->value); \ - } \ - } \ - } \ -\ - memset(_map_->buffer, 0, sizeof(struct CMC_DEF_ENTRY(SNAME)) * _map_->capacity); \ -\ - _map_->count = 0; \ - _map_->flag = CMC_FLAG_OK; \ - } \ -\ - void CMC_(PFX, _free)(struct SNAME * _map_) \ - { \ - if (_map_->f_key->free || _map_->f_val->free) \ - { \ - for (size_t i = 0; i < _map_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = &(_map_->buffer[i]); \ -\ - if (entry->state == CMC_ES_FILLED) \ - { \ - if (_map_->f_key->free) \ - _map_->f_key->free(entry->key); \ - if (_map_->f_val->free) \ - _map_->f_val->free(entry->value); \ - } \ - } \ - } \ -\ - _map_->alloc->free(_map_->buffer); \ - _map_->alloc->free(_map_); \ - } \ -\ - void CMC_(PFX, _customize)(struct SNAME * _map_, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - if (!alloc) \ - _map_->alloc = &cmc_alloc_node_default; \ - else \ - _map_->alloc = alloc; \ -\ - CMC_CALLBACKS_ASSIGN(_map_, callbacks); \ -\ - _map_->flag = CMC_FLAG_OK; \ - } \ -\ - bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value) \ - { \ - if (CMC_(PFX, _full)(_map_)) \ - { \ - if (!CMC_(PFX, _resize)(_map_, _map_->capacity + 1)) \ - return false; \ - } \ -\ - if (CMC_(PFX, _impl_get_entry)(_map_, key) != NULL) \ - { \ - _map_->flag = CMC_FLAG_DUPLICATE; \ - return false; \ - } \ -\ - size_t hash = _map_->f_key->hash(key); \ - size_t original_pos = hash % _map_->capacity; \ - size_t pos = original_pos; \ -\ - struct CMC_DEF_ENTRY(SNAME) *target = &(_map_->buffer[pos]); \ -\ - if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) \ - { \ - target->key = key; \ - target->value = value; \ - target->dist = 0; \ - target->state = CMC_ES_FILLED; \ - } \ - else \ - { \ - while (true) \ - { \ - pos++; \ - target = &(_map_->buffer[pos % _map_->capacity]); \ -\ - if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) \ - { \ - target->key = key; \ - target->value = value; \ - target->dist = pos - original_pos; \ - target->state = CMC_ES_FILLED; \ -\ - break; \ - } \ - else if (target->dist < pos - original_pos) \ - { \ - K tmp_k = target->key; \ - V tmp_v = target->value; \ - size_t tmp_dist = target->dist; \ -\ - target->key = key; \ - target->value = value; \ - target->dist = pos - original_pos; \ -\ - key = tmp_k; \ - value = tmp_v; \ - original_pos = pos - tmp_dist; \ - } \ - } \ - } \ -\ - _map_->count++; \ - _map_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_map_, create); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _update)(struct SNAME * _map_, K key, V new_value, V * old_value) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_map_, key); \ -\ - if (!entry) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return false; \ - } \ -\ - if (old_value) \ - *old_value = entry->value; \ -\ - entry->value = new_value; \ -\ - _map_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_map_, update); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _remove)(struct SNAME * _map_, K key, V * out_value) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - struct CMC_DEF_ENTRY(SNAME) *result = CMC_(PFX, _impl_get_entry)(_map_, key); \ -\ - if (result == NULL) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return false; \ - } \ -\ - if (out_value) \ - *out_value = result->value; \ -\ - result->key = (K){ 0 }; \ - result->value = (V){ 0 }; \ - result->dist = 0; \ - result->state = CMC_ES_DELETED; \ -\ - _map_->count--; \ - _map_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_map_, delete); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _max)(struct SNAME * _map_, K * key, V * value) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - bool first = true; \ - K max_key = (K){ 0 }; \ - V max_val = (V){ 0 }; \ -\ - for (size_t i = 0; i < _map_->capacity; i++) \ - { \ - if (_map_->buffer[i].state == CMC_ES_FILLED) \ - { \ - if (first) \ - { \ - max_key = _map_->buffer[i].key; \ - max_val = _map_->buffer[i].value; \ - first = false; \ - } \ - else if (_map_->f_key->cmp(_map_->buffer[i].key, max_key) > 0) \ - { \ - max_key = _map_->buffer[i].key; \ - max_val = _map_->buffer[i].value; \ - } \ - } \ - } \ -\ - if (key) \ - *key = max_key; \ - if (value) \ - *value = max_val; \ -\ - _map_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_map_, read); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _min)(struct SNAME * _map_, K * key, V * value) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - bool first = true; \ - K min_key = (K){ 0 }; \ - V min_val = (V){ 0 }; \ -\ - for (size_t i = 0; i < _map_->capacity; i++) \ - { \ - if (_map_->buffer[i].state == CMC_ES_FILLED) \ - { \ - if (first) \ - { \ - min_key = _map_->buffer[i].key; \ - min_val = _map_->buffer[i].value; \ - first = false; \ - } \ - else if (_map_->f_key->cmp(_map_->buffer[i].key, min_key) < 0) \ - { \ - min_key = _map_->buffer[i].key; \ - min_val = _map_->buffer[i].value; \ - } \ - } \ - } \ -\ - if (key) \ - *key = min_key; \ - if (value) \ - *value = min_val; \ -\ - _map_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_map_, read); \ -\ - return true; \ - } \ -\ - V CMC_(PFX, _get)(struct SNAME * _map_, K key) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ -\ - struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_map_, key); \ -\ - if (!entry) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return (V){ 0 }; \ - } \ -\ - _map_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_map_, read); \ -\ - return entry->value; \ - } \ -\ - V *CMC_(PFX, _get_ref)(struct SNAME * _map_, K key) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return NULL; \ - } \ -\ - struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_map_, key); \ -\ - if (!entry) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return NULL; \ - } \ -\ - _map_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_map_, read); \ -\ - return &(entry->value); \ - } \ -\ - bool CMC_(PFX, _contains)(struct SNAME * _map_, K key) \ - { \ - _map_->flag = CMC_FLAG_OK; \ -\ - bool result = CMC_(PFX, _impl_get_entry)(_map_, key) != NULL; \ -\ - CMC_CALLBACKS_CALL(_map_, read); \ -\ - return result; \ - } \ -\ - bool CMC_(PFX, _empty)(struct SNAME * _map_) \ - { \ - return _map_->count == 0; \ - } \ -\ - bool CMC_(PFX, _full)(struct SNAME * _map_) \ - { \ - return (double)_map_->capacity * _map_->load <= (double)_map_->count; \ - } \ -\ - size_t CMC_(PFX, _count)(struct SNAME * _map_) \ - { \ - return _map_->count; \ - } \ -\ - size_t CMC_(PFX, _capacity)(struct SNAME * _map_) \ - { \ - return _map_->capacity; \ - } \ -\ - double CMC_(PFX, _load)(struct SNAME * _map_) \ - { \ - return _map_->load; \ - } \ -\ - int CMC_(PFX, _flag)(struct SNAME * _map_) \ - { \ - return _map_->flag; \ - } \ -\ - bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity) \ - { \ - _map_->flag = CMC_FLAG_OK; \ -\ - if (_map_->capacity == capacity) \ - goto success; \ -\ - if (_map_->capacity > capacity / _map_->load) \ - goto success; \ -\ - /* Prevent integer overflow */ \ - if (capacity >= UINTMAX_MAX * _map_->load) \ - { \ - _map_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ -\ - /* Calculate required capacity based on the prime numbers */ \ - size_t theoretical_size = CMC_(PFX, _impl_calculate_size)(capacity); \ -\ - /* Not possible to shrink with current available prime numbers */ \ - if (theoretical_size < _map_->count / _map_->load) \ - { \ - _map_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ -\ - /* No callbacks since _new_map_ is just a temporary hashtable */ \ - struct SNAME *_new_map_ = \ - CMC_(PFX, _new_custom)(capacity, _map_->load, _map_->f_key, _map_->f_val, _map_->alloc, NULL); \ -\ - if (!_new_map_) \ - { \ - _map_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ -\ - for (size_t i = 0; i < _map_->capacity; i++) \ - { \ - if (_map_->buffer[i].state == CMC_ES_FILLED) \ - { \ - K key = _map_->buffer[i].key; \ - V value = _map_->buffer[i].value; \ -\ - /* TODO check this for possible errors */ \ - CMC_(PFX, _insert)(_new_map_, key, value); \ - } \ - } \ -\ - /* Unlikely */ \ - if (_map_->count != _new_map_->count) \ - { \ - CMC_(PFX, _free)(_new_map_); \ -\ - _map_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ -\ - struct CMC_DEF_ENTRY(SNAME) *tmp_b = _map_->buffer; \ - _map_->buffer = _new_map_->buffer; \ - _new_map_->buffer = tmp_b; \ -\ - size_t tmp_c = _map_->capacity; \ - _map_->capacity = _new_map_->capacity; \ - _new_map_->capacity = tmp_c; \ -\ - /* Prevent the map from freeing the data */ \ - _new_map_->f_key = &(struct CMC_DEF_FKEY(SNAME)){ NULL }; \ - _new_map_->f_val = &(struct CMC_DEF_FVAL(SNAME)){ NULL }; \ -\ - CMC_(PFX, _free)(_new_map_); \ -\ - success: \ -\ - CMC_CALLBACKS_CALL(_map_, resize); \ -\ - return true; \ - } \ -\ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_) \ - { \ - struct SNAME *result = CMC_(PFX, _new_custom)(_map_->capacity * _map_->load, _map_->load, _map_->f_key, \ - _map_->f_val, _map_->alloc, NULL); \ -\ - if (!result) \ - { \ - _map_->flag = CMC_FLAG_ERROR; \ - return NULL; \ - } \ -\ - CMC_CALLBACKS_ASSIGN(result, _map_->callbacks); \ -\ - if (_map_->f_key->cpy || _map_->f_val->cpy) \ - { \ - for (size_t i = 0; i < _map_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *scan = &(_map_->buffer[i]); \ -\ - if (scan->state != CMC_ES_EMPTY) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *target = &(result->buffer[i]); \ -\ - if (scan->state == CMC_ES_DELETED) \ - target->state = CMC_ES_DELETED; \ - else \ - { \ - target->state = scan->state; \ - target->dist = scan->dist; \ -\ - if (_map_->f_key->cpy) \ - target->key = _map_->f_key->cpy(scan->key); \ - else \ - target->key = scan->key; \ -\ - if (_map_->f_val->cpy) \ - target->value = _map_->f_val->cpy(scan->value); \ - else \ - target->value = scan->value; \ - } \ - } \ - } \ - } \ - else \ - memcpy(result->buffer, _map_->buffer, sizeof(struct CMC_DEF_ENTRY(SNAME)) * _map_->capacity); \ -\ - result->count = _map_->count; \ -\ - _map_->flag = CMC_FLAG_OK; \ -\ - return result; \ - } \ -\ - bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_) \ - { \ - _map1_->flag = CMC_FLAG_OK; \ - _map2_->flag = CMC_FLAG_OK; \ -\ - if (_map1_->count != _map2_->count) \ - return false; \ -\ - /* Optimize loop using the smallest hashtable */ \ - struct SNAME *_map_a_; \ - struct SNAME *_map_b_; \ -\ - _map_a_ = _map1_->capacity < _map2_->capacity ? _map1_ : _map2_; \ - _map_b_ = _map_a_ == _map1_ ? _map2_ : _map1_; \ -\ - for (size_t i = 0; i < _map_a_->capacity; i++) \ - { \ - if (_map_a_->buffer[i].state == CMC_ES_FILLED) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry_a = &(_map_a_->buffer[i]); \ - struct CMC_DEF_ENTRY(SNAME) *entry_b = CMC_(PFX, _impl_get_entry)(_map_b_, entry_a->key); \ -\ - if (!entry_b) \ - return false; \ -\ - if (_map_a_->f_val->cmp(entry_a->value, entry_b->value) != 0) \ - return false; \ - } \ - } \ -\ - return true; \ - } \ -\ - static struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_get_entry)(struct SNAME * _map_, K key) \ - { \ - size_t hash = _map_->f_key->hash(key); \ - size_t pos = hash % _map_->capacity; \ -\ - struct CMC_DEF_ENTRY(SNAME) *target = &(_map_->buffer[pos]); \ -\ - while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED) \ - { \ - if (_map_->f_key->cmp(target->key, key) == 0) \ - return target; \ -\ - pos++; \ - target = &(_map_->buffer[pos % _map_->capacity]); \ - } \ -\ - return NULL; \ - } \ -\ - static size_t CMC_(PFX, _impl_calculate_size)(size_t required) \ - { \ - const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); \ -\ - if (cmc_hashtable_primes[count - 1] < required) \ - return required; \ -\ - size_t i = 0; \ - while (cmc_hashtable_primes[i] < required) \ - i++; \ -\ - return cmc_hashtable_primes[i]; \ - } - -#endif /* CMC_CMC_HASHMAP_H */ diff --git a/src/cmc_hashmultimap.h b/src/cmc_hashmultimap.h deleted file mode 100644 index 9f6cd36..0000000 --- a/src/cmc_hashmultimap.h +++ /dev/null @@ -1,1111 +0,0 @@ -/** - * Copyright (c) 2019 Leonardo Vencovsky - * - * This file is part of the C Macro Collections Libray. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * cmc_hashmultimap.h - * - * Creation Date: 26/04/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -/** - * HashMultiMap - * - * The HashMultiMap is a Map that allows for multiple keys. This is a data - * structure that has a very narrow usage. A Map (either TreeMap or HashMap) can - * also work like a HashMultiMap if a certain key is mapped to another - * collection. - * - * Map> maps an integer to a list of integer. - * HashMultiMap maps many integer keys to integer values. - * - * The difference is that in a HashMultiMap you can store keys that are the same - * but might be different instances of the same value. This is also relevant if - * your data type is more complex like a struct where its ID is the same but - * some other members of this data type are different. - * - * Implementation - * - * The map uses separate chaining and robin hood hashing. Its internal buffer - * is made of a pair of pointers to entries that represent a linked list. So - * accessing map->buffer[0] would give the first pair of pointers. Each entry - * has both a pointer to a previous entry and a next entry. This design choice - * was made so that every collection in this library has a two-way iterator - * with a very few exceptions. - * - * Each entry is composed of a Key and a Value. Entries with the same key should - * always hash to the same linked list. Also, keys that hash to the same bucket - * will also be in the same linked list. - * - * The order of inserting and removing the same keys will behave like a FIFO. So - * the first key added will be the first to be removed. - */ - -#ifndef CMC_CMC_HASHMULTIMAP_H -#define CMC_CMC_HASHMULTIMAP_H - -/* ------------------------------------------------------------------------- - * Core functionalities of the C Macro Collections Library - * ------------------------------------------------------------------------- */ -#include "cor_core.h" - -/* ------------------------------------------------------------------------- - * Hashtable Implementation - * ------------------------------------------------------------------------- */ -#include "cor_hashtable.h" - -/** - * Core HashMultiMap implementation - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_CMC_HASHMULTIMAP_CORE(ACCESS, FILE, PARAMS) \ - CMC_(CMC_(CMC_CMC_HASHMULTIMAP_CORE_, ACCESS), CMC_(_, FILE))(PARAMS) - -/* PRIVATE or PUBLIC solver */ -#define CMC_CMC_HASHMULTIMAP_CORE_PUBLIC_HEADER(PARAMS) \ - CMC_CMC_HASHMULTIMAP_CORE_STRUCT(PARAMS) \ - CMC_CMC_HASHMULTIMAP_CORE_HEADER(PARAMS) - -#define CMC_CMC_HASHMULTIMAP_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_HASHMULTIMAP_CORE_SOURCE(PARAMS) - -#define CMC_CMC_HASHMULTIMAP_CORE_PRIVATE_HEADER(PARAMS) \ - struct CMC_PARAM_SNAME(PARAMS); \ - struct CMC_DEF_ENTRY(CMC_PARAM_SNAME(PARAMS)); \ - CMC_CMC_HASHMULTIMAP_CORE_HEADER(PARAMS) - -#define CMC_CMC_HASHMULTIMAP_CORE_PRIVATE_SOURCE(PARAMS) \ - CMC_CMC_HASHMULTIMAP_CORE_STRUCT(PARAMS) \ - CMC_CMC_HASHMULTIMAP_CORE_SOURCE(PARAMS) - -/* Lowest level API */ -#define CMC_CMC_HASHMULTIMAP_CORE_STRUCT(PARAMS) \ - CMC_CMC_HASHMULTIMAP_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_CMC_HASHMULTIMAP_CORE_HEADER(PARAMS) \ - CMC_CMC_HASHMULTIMAP_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_CMC_HASHMULTIMAP_CORE_SOURCE(PARAMS) \ - CMC_CMC_HASHMULTIMAP_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -/* ------------------------------------------------------------------------- - * Struct - * ------------------------------------------------------------------------- */ -#define CMC_CMC_HASHMULTIMAP_CORE_STRUCT_(PFX, SNAME, K, V) \ -\ - /* HashMultimap Structure */ \ - struct SNAME \ - { \ - /* Array of linked list to entries */ \ - struct CMC_DEF_ENTRY(SNAME) * (*buffer)[2]; \ -\ - /* Current array capacity */ \ - size_t capacity; \ -\ - /* Current amount of keys */ \ - size_t count; \ -\ - /* Load factor in range (0.0, infinity) */ \ - double load; \ -\ - /* Flags indicating errors or success */ \ - int flag; \ -\ - /* Key function table */ \ - struct CMC_DEF_FKEY(SNAME) * f_key; \ -\ - /* Value function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ -\ - /* Custom allocation functions */ \ - struct CMC_ALLOC_NODE_NAME *alloc; \ -\ - /* Custom callback functions */ \ - CMC_CALLBACKS_DECL; \ - }; \ -\ - /* HashMultimap Entry */ \ - struct CMC_DEF_ENTRY(SNAME) \ - { \ - /* Entry Key */ \ - K key; \ -\ - /* Entry Value */ \ - V value; \ -\ - /* Next entry on the linked list */ \ - struct CMC_DEF_ENTRY(SNAME) * next; \ -\ - /* Previous entry on the linked list */ \ - struct CMC_DEF_ENTRY(SNAME) * prev; \ - }; - -/* ------------------------------------------------------------------------- - * Header - * ------------------------------------------------------------------------- */ -#define CMC_CMC_HASHMULTIMAP_CORE_HEADER_(PFX, SNAME, K, V) \ -\ - /* Key struct function table */ \ - struct CMC_DEF_FKEY(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(K); \ -\ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(K); \ -\ - /* To string function */ \ - CMC_DEF_FTAB_STR(K); \ -\ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(K); \ -\ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(K); \ -\ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(K); \ - }; \ -\ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(V); \ -\ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(V); \ -\ - /* To string function */ \ - CMC_DEF_FTAB_STR(V); \ -\ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(V); \ -\ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(V); \ -\ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(V); \ - }; \ -\ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \ - struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \ - struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks); \ - void CMC_(PFX, _clear)(struct SNAME * _map_); \ - void CMC_(PFX, _free)(struct SNAME * _map_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _map_, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value); \ - bool CMC_(PFX, _update)(struct SNAME * _map_, K key, V new_value, V * old_value); \ - size_t CMC_(PFX, _update_all)(struct SNAME * _map_, K key, V new_value, V * *old_values); \ - bool CMC_(PFX, _remove)(struct SNAME * _map_, K key, V * out_value); \ - size_t CMC_(PFX, _remove_all)(struct SNAME * _map_, K key, V * *out_values); \ - /* Element Access */ \ - bool CMC_(PFX, _max)(struct SNAME * _map_, K * key, V * value); \ - bool CMC_(PFX, _min)(struct SNAME * _map_, K * key, V * value); \ - V CMC_(PFX, _get)(struct SNAME * _map_, K key); \ - V *CMC_(PFX, _get_ref)(struct SNAME * _map_, K key); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _map_, K key); \ - bool CMC_(PFX, _empty)(struct SNAME * _map_); \ - bool CMC_(PFX, _full)(struct SNAME * _map_); \ - size_t CMC_(PFX, _count)(struct SNAME * _map_); \ - size_t CMC_(PFX, _key_count)(struct SNAME * _map_, K key); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _map_); \ - double CMC_(PFX, _load)(struct SNAME * _map_); \ - int CMC_(PFX, _flag)(struct SNAME * _map_); \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_); \ - bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_); - -/* ------------------------------------------------------------------------- - * Source - * ------------------------------------------------------------------------- */ -#define CMC_CMC_HASHMULTIMAP_CORE_SOURCE_(PFX, SNAME, K, V) \ -\ - /* Implementation Detail Functions */ \ - struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_new_entry)(struct SNAME * _map_, K key, V value); \ - struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_get_entry)(struct SNAME * _map_, K key); \ - size_t CMC_(PFX, _impl_key_count)(struct SNAME * _map_, K key); \ - size_t CMC_(PFX, _impl_calculate_size)(size_t required); \ -\ - struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \ - struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - return CMC_(PFX, _new_custom)(capacity, load, f_key, f_val, NULL, NULL); \ - } \ -\ - struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \ - struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - if (capacity == 0 || load <= 0) \ - return NULL; \ -\ - /* Prevent integer overflow */ \ - if (capacity >= UINTMAX_MAX * load) \ - return NULL; \ -\ - if (!f_key || !f_val) \ - return NULL; \ -\ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ -\ - size_t real_capacity = CMC_(PFX, _impl_calculate_size)(capacity / load); \ -\ - struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \ -\ - if (!_map_) \ - return NULL; \ -\ - _map_->buffer = alloc->calloc(real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME) *[2])); \ -\ - if (!_map_->buffer) \ - { \ - alloc->free(_map_); \ - return NULL; \ - } \ -\ - _map_->count = 0; \ - _map_->capacity = real_capacity; \ - _map_->load = load; \ - _map_->flag = CMC_FLAG_OK; \ - _map_->f_key = f_key; \ - _map_->f_val = f_val; \ - _map_->alloc = alloc; \ - CMC_CALLBACKS_ASSIGN(_map_, callbacks); \ -\ - return _map_; \ - } \ -\ - void CMC_(PFX, _clear)(struct SNAME * _map_) \ - { \ - for (size_t i = 0; i < _map_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[i][0]; \ -\ - while (scan) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *next = scan->next; \ -\ - if (_map_->f_key->free) \ - _map_->f_key->free(scan->key); \ - if (_map_->f_val->free) \ - _map_->f_val->free(scan->value); \ -\ - _map_->alloc->free(scan); \ -\ - scan = next; \ - } \ - } \ -\ - memset(_map_->buffer, 0, sizeof(struct CMC_DEF_ENTRY(SNAME) *[2]) * _map_->capacity); \ -\ - _map_->count = 0; \ - _map_->flag = CMC_FLAG_OK; \ - } \ -\ - void CMC_(PFX, _free)(struct SNAME * _map_) \ - { \ - size_t index = 0; \ -\ - while (index < _map_->capacity) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[index][0]; \ -\ - if (scan) \ - { \ - if (scan->next == NULL && scan->prev == NULL) \ - { \ - if (_map_->f_key->free) \ - _map_->f_key->free(scan->key); \ - if (_map_->f_val->free) \ - _map_->f_val->free(scan->value); \ -\ - _map_->alloc->free(scan); \ - } \ - else \ - { \ - while (scan) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *tmp = scan; \ -\ - scan = scan->next; \ -\ - if (_map_->f_key->free) \ - _map_->f_key->free(tmp->key); \ - if (_map_->f_val->free) \ - _map_->f_val->free(tmp->value); \ -\ - _map_->alloc->free(tmp); \ - } \ - } \ - } \ -\ - index++; \ - } \ -\ - _map_->alloc->free(_map_->buffer); \ - _map_->alloc->free(_map_); \ - } \ -\ - void CMC_(PFX, _customize)(struct SNAME * _map_, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - if (!alloc) \ - _map_->alloc = &cmc_alloc_node_default; \ - else \ - _map_->alloc = alloc; \ -\ - CMC_CALLBACKS_ASSIGN(_map_, callbacks); \ -\ - _map_->flag = CMC_FLAG_OK; \ - } \ -\ - bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value) \ - { \ - if (CMC_(PFX, _full)(_map_)) \ - { \ - if (!CMC_(PFX, _resize)(_map_, _map_->capacity + 1)) \ - return false; \ - } \ -\ - size_t hash = _map_->f_key->hash(key); \ - size_t pos = hash % _map_->capacity; \ -\ - struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_new_entry)(_map_, key, value); \ -\ - if (_map_->buffer[pos][0] == NULL) \ - { \ - _map_->buffer[pos][0] = entry; \ - _map_->buffer[pos][1] = entry; \ - } \ - else \ - { \ - entry->prev = _map_->buffer[pos][1]; \ -\ - _map_->buffer[pos][1]->next = entry; \ - _map_->buffer[pos][1] = entry; \ - } \ -\ - _map_->count++; \ - _map_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_map_, create); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _update)(struct SNAME * _map_, K key, V new_value, V * old_value) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_map_, key); \ -\ - if (!entry) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return false; \ - } \ -\ - if (old_value) \ - *old_value = entry->value; \ -\ - entry->value = new_value; \ -\ - _map_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_map_, update); \ -\ - return true; \ - } \ -\ - size_t CMC_(PFX, _update_all)(struct SNAME * _map_, K key, V new_value, V * *old_values) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return 0; \ - } \ -\ - size_t hash = _map_->f_key->hash(key); \ -\ - struct CMC_DEF_ENTRY(SNAME) *entry = _map_->buffer[hash % _map_->capacity][0]; \ -\ - if (entry == NULL) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return 0; \ - } \ -\ - if (old_values) \ - { \ - size_t total = CMC_(PFX, _impl_key_count)(_map_, key); \ -\ - if (total == 0) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return 0; \ - } \ -\ - *old_values = _map_->alloc->malloc(sizeof(V) * total); \ -\ - if (!(*old_values)) \ - { \ - _map_->flag = CMC_FLAG_ALLOC; \ - return 0; \ - } \ - } \ -\ - size_t index = 0; \ -\ - while (entry) \ - { \ - if (_map_->f_key->cmp(entry->key, key) == 0) \ - { \ - if (old_values) \ - (*old_values)[index] = entry->value; \ -\ - index++; \ - entry->value = new_value; \ - } \ -\ - entry = entry->next; \ - } \ -\ - _map_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_map_, update); \ -\ - return index; \ - } \ -\ - bool CMC_(PFX, _remove)(struct SNAME * _map_, K key, V * out_value) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - size_t hash = _map_->f_key->hash(key); \ -\ - struct CMC_DEF_ENTRY(SNAME) **head = &(_map_->buffer[hash % _map_->capacity][0]); \ - struct CMC_DEF_ENTRY(SNAME) **tail = &(_map_->buffer[hash % _map_->capacity][1]); \ -\ - if (*head == NULL) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return false; \ - } \ -\ - struct CMC_DEF_ENTRY(SNAME) *entry = *head; \ -\ - if (entry->next == NULL && entry->prev == NULL) \ - { \ - if (_map_->f_key->cmp(entry->key, key) == 0) \ - { \ - *head = NULL; \ - *tail = NULL; \ -\ - if (out_value) \ - *out_value = entry->value; \ - } \ - else \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return false; \ - } \ - } \ - else \ - { \ - bool found = false; \ -\ - while (entry) \ - { \ - if (_map_->f_key->cmp(entry->key, key) == 0) \ - { \ - if (*head == entry) \ - *head = entry->next; \ - if (*tail == entry) \ - *tail = entry->prev; \ -\ - if (entry->prev) \ - entry->prev->next = entry->next; \ - if (entry->next) \ - entry->next->prev = entry->prev; \ -\ - if (out_value) \ - *out_value = entry->value; \ -\ - found = true; \ -\ - break; \ - } \ - else \ - entry = entry->next; \ - } \ -\ - if (!found) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return false; \ - } \ - } \ -\ - _map_->alloc->free(entry); \ -\ - _map_->count--; \ - _map_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_map_, delete); \ -\ - return true; \ - } \ -\ - size_t CMC_(PFX, _remove_all)(struct SNAME * _map_, K key, V * *out_values) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - size_t hash = _map_->f_key->hash(key); \ -\ - struct CMC_DEF_ENTRY(SNAME) **head = &(_map_->buffer[hash % _map_->capacity][0]); \ - struct CMC_DEF_ENTRY(SNAME) **tail = &(_map_->buffer[hash % _map_->capacity][1]); \ -\ - if (*head == NULL) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return 0; \ - } \ -\ - if (out_values) \ - { \ - size_t total = CMC_(PFX, _impl_key_count)(_map_, key); \ -\ - if (total == 0) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return 0; \ - } \ -\ - *out_values = _map_->alloc->malloc(sizeof(V) * total); \ -\ - if (!(*out_values)) \ - { \ - _map_->flag = CMC_FLAG_ALLOC; \ - return 0; \ - } \ - } \ -\ - size_t index = 0; \ - struct CMC_DEF_ENTRY(SNAME) *entry = *head; \ -\ - if (entry->next == NULL) \ - { \ - *head = NULL; \ - *tail = NULL; \ -\ - if (out_values) \ - (*out_values)[index] = entry->value; \ -\ - index++; \ - _map_->alloc->free(entry); \ - } \ - else \ - { \ - while (entry) \ - { \ - if (_map_->f_key->cmp(entry->key, key) == 0) \ - { \ - if (*head == entry) \ - *head = entry->next; \ - if (*tail == entry) \ - *tail = entry->prev; \ -\ - struct CMC_DEF_ENTRY(SNAME) *next = entry->next; \ -\ - if (entry->prev) \ - entry->prev->next = entry->next; \ - if (entry->next) \ - entry->next->prev = entry->prev; \ -\ - if (out_values) \ - (*out_values)[index] = entry->value; \ -\ - index++; \ - _map_->alloc->free(entry); \ -\ - entry = next; \ - } \ - else \ - entry = entry->next; \ - } \ - } \ -\ - _map_->count -= index; \ - _map_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_map_, delete); \ -\ - return index; \ - } \ -\ - bool CMC_(PFX, _max)(struct SNAME * _map_, K * key, V * value) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - bool first = true; \ - K max_key = (K){ 0 }; \ - V max_val = (V){ 0 }; \ -\ - for (size_t i = 0; i < _map_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[i][0]; \ -\ - while (scan) \ - { \ - if (first) \ - { \ - max_key = scan->key; \ - max_val = scan->value; \ -\ - first = false; \ - } \ - else if (_map_->f_key->cmp(scan->key, max_key) > 0) \ - { \ - max_key = scan->key; \ - max_val = scan->value; \ - } \ -\ - scan = scan->next; \ - } \ - } \ -\ - if (key) \ - *key = max_key; \ - if (value) \ - *value = max_val; \ -\ - _map_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_map_, read); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _min)(struct SNAME * _map_, K * key, V * value) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - bool first = true; \ - K min_key = (K){ 0 }; \ - V min_val = (V){ 0 }; \ -\ - for (size_t i = 0; i < _map_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[i][0]; \ -\ - while (scan) \ - { \ - if (first) \ - { \ - min_key = scan->key; \ - min_val = scan->value; \ -\ - first = false; \ - } \ - else if (_map_->f_key->cmp(scan->key, min_key) < 0) \ - { \ - min_key = scan->key; \ - min_val = scan->value; \ - } \ -\ - scan = scan->next; \ - } \ - } \ -\ - if (key) \ - *key = min_key; \ - if (value) \ - *value = min_val; \ -\ - _map_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_map_, read); \ -\ - return true; \ - } \ -\ - V CMC_(PFX, _get)(struct SNAME * _map_, K key) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ -\ - struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_map_, key); \ -\ - if (!entry) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return (V){ 0 }; \ - } \ -\ - _map_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_map_, read); \ -\ - return entry->value; \ - } \ -\ - V *CMC_(PFX, _get_ref)(struct SNAME * _map_, K key) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return NULL; \ - } \ -\ - struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_map_, key); \ -\ - if (!entry) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return NULL; \ - } \ -\ - _map_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_map_, read); \ -\ - return &(entry->value); \ - } \ -\ - bool CMC_(PFX, _contains)(struct SNAME * _map_, K key) \ - { \ - _map_->flag = CMC_FLAG_OK; \ -\ - bool result = CMC_(PFX, _impl_get_entry)(_map_, key) != NULL; \ -\ - CMC_CALLBACKS_CALL(_map_, read); \ -\ - return result; \ - } \ -\ - bool CMC_(PFX, _empty)(struct SNAME * _map_) \ - { \ - return _map_->count == 0; \ - } \ -\ - bool CMC_(PFX, _full)(struct SNAME * _map_) \ - { \ - return (double)_map_->capacity * _map_->load <= (double)_map_->count; \ - } \ -\ - size_t CMC_(PFX, _count)(struct SNAME * _map_) \ - { \ - return _map_->count; \ - } \ -\ - size_t CMC_(PFX, _key_count)(struct SNAME * _map_, K key) \ - { \ - return CMC_(PFX, _impl_key_count)(_map_, key); \ - } \ -\ - size_t CMC_(PFX, _capacity)(struct SNAME * _map_) \ - { \ - return _map_->capacity; \ - } \ -\ - double CMC_(PFX, _load)(struct SNAME * _map_) \ - { \ - return _map_->load; \ - } \ -\ - int CMC_(PFX, _flag)(struct SNAME * _map_) \ - { \ - return _map_->flag; \ - } \ -\ - bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity) \ - { \ - _map_->flag = CMC_FLAG_OK; \ -\ - if (_map_->capacity == capacity) \ - goto success; \ -\ - if (_map_->capacity > capacity / _map_->load) \ - goto success; \ -\ - /* Prevent integer overflow */ \ - if (capacity >= UINTMAX_MAX * _map_->load) \ - { \ - _map_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ -\ - /* Calculate required capacity based on the prime numbers */ \ - size_t theoretical_size = CMC_(PFX, _impl_calculate_size)(capacity); \ -\ - /* Not possible to shrink with current available prime numbers */ \ - if (theoretical_size < _map_->count / _map_->load) \ - { \ - _map_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ -\ - /* No callbacks since _new_map_ is just a temporary hashtable */ \ - struct SNAME *_new_map_ = \ - CMC_(PFX, _new_custom)(capacity, _map_->load, _map_->f_key, _map_->f_val, _map_->alloc, NULL); \ -\ - if (!_new_map_) \ - { \ - _map_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ -\ - for (size_t i = 0; i < _map_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[i][0]; \ -\ - while (scan) \ - { \ - /* TODO check for errors */ \ - CMC_(PFX, _insert)(_new_map_, scan->key, scan->value); \ -\ - scan = scan->next; \ - } \ - } \ -\ - if (_map_->count != _new_map_->count) \ - { \ - CMC_(PFX, _free)(_new_map_); \ -\ - _map_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ -\ - struct CMC_DEF_ENTRY(SNAME) * (*tmp_b)[2] = _map_->buffer; \ - _map_->buffer = _new_map_->buffer; \ - _new_map_->buffer = tmp_b; \ -\ - size_t tmp_c = _map_->capacity; \ - _map_->capacity = _new_map_->capacity; \ - _new_map_->capacity = tmp_c; \ -\ - /* Prevent the map from freeing the data */ \ - _new_map_->f_key = &(struct CMC_DEF_FKEY(SNAME)){ NULL }; \ - _new_map_->f_val = &(struct CMC_DEF_FVAL(SNAME)){ NULL }; \ -\ - CMC_(PFX, _free)(_new_map_); \ -\ - success: \ -\ - CMC_CALLBACKS_CALL(_map_, resize); \ -\ - return true; \ - } \ -\ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_) \ - { \ - /* Callback will be added later */ \ - struct SNAME *result = CMC_(PFX, _new_custom)(_map_->capacity * _map_->load, _map_->load, _map_->f_key, \ - _map_->f_val, _map_->alloc, NULL); \ -\ - if (!result) \ - { \ - _map_->flag = CMC_FLAG_ERROR; \ - return NULL; \ - } \ -\ - for (size_t i = 0; i < _map_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[i][0]; \ -\ - while (scan) \ - { \ - K key; \ - V value; \ -\ - if (_map_->f_key->cpy) \ - key = _map_->f_key->cpy(scan->key); \ - else \ - key = scan->key; \ - if (_map_->f_val->cpy) \ - value = _map_->f_val->cpy(scan->value); \ - else \ - value = scan->value; \ -\ - /* TODO check for errors */ \ - CMC_(PFX, _insert)(result, key, value); \ -\ - scan = scan->next; \ - } \ - } \ -\ - CMC_CALLBACKS_ASSIGN(result, _map_->callbacks); \ - _map_->flag = CMC_FLAG_OK; \ -\ - return result; \ - } \ -\ - bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_) \ - { \ - _map1_->flag = CMC_FLAG_OK; \ - _map2_->flag = CMC_FLAG_OK; \ -\ - if (_map1_->count != _map2_->count) \ - return false; \ -\ - /* Optimize loop using the smallest hashtable */ \ - struct SNAME *_map_a_; \ - struct SNAME *_map_b_; \ -\ - _map_a_ = _map1_->capacity < _map2_->capacity ? _map1_ : _map2_; \ - _map_b_ = _map_a_ == _map1_ ? _map2_ : _map1_; \ -\ - for (size_t i = 0; i < _map_a_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *scan = _map_a_->buffer[i][0]; \ -\ - while (scan) \ - { \ - /* OPTIMIZE - This is calling key_count for repeating keys */ \ - if (CMC_(PFX, _impl_key_count)(_map_a_, scan->key) != CMC_(PFX, _impl_key_count)(_map_b_, scan->key)) \ - return false; \ -\ - scan = scan->next; \ - } \ - } \ -\ - return true; \ - } \ -\ - struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_new_entry)(struct SNAME * _map_, K key, V value) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = _map_->alloc->malloc(sizeof(struct CMC_DEF_ENTRY(SNAME))); \ -\ - if (!entry) \ - return NULL; \ -\ - entry->key = key; \ - entry->value = value; \ - entry->next = NULL; \ - entry->prev = NULL; \ -\ - return entry; \ - } \ -\ - struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_get_entry)(struct SNAME * _map_, K key) \ - { \ - size_t hash = _map_->f_key->hash(key); \ -\ - struct CMC_DEF_ENTRY(SNAME) *entry = _map_->buffer[hash % _map_->capacity][0]; \ -\ - while (entry) \ - { \ - if (_map_->f_key->cmp(entry->key, key) == 0) \ - return entry; \ -\ - entry = entry->next; \ - } \ -\ - return NULL; \ - } \ -\ - size_t CMC_(PFX, _impl_key_count)(struct SNAME * _map_, K key) \ - { \ - size_t hash = _map_->f_key->hash(key); \ -\ - struct CMC_DEF_ENTRY(SNAME) *entry = _map_->buffer[hash % _map_->capacity][0]; \ -\ - size_t total_count = 0; \ -\ - if (!entry) \ - return total_count; \ -\ - while (entry) \ - { \ - if (_map_->f_key->cmp(entry->key, key) == 0) \ - total_count++; \ -\ - entry = entry->next; \ - } \ -\ - return total_count; \ - } \ -\ - size_t CMC_(PFX, _impl_calculate_size)(size_t required) \ - { \ - const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); \ -\ - if (cmc_hashtable_primes[count - 1] < required) \ - return required; \ -\ - size_t i = 0; \ - while (cmc_hashtable_primes[i] < required) \ - i++; \ -\ - return cmc_hashtable_primes[i]; \ - } - -#endif /* CMC_CMC_HASHMULTIMAP_H */ diff --git a/src/cmc_hashmultiset.h b/src/cmc_hashmultiset.h deleted file mode 100644 index 05ddcdc..0000000 --- a/src/cmc_hashmultiset.h +++ /dev/null @@ -1,925 +0,0 @@ -/** - * Copyright (c) 2019 Leonardo Vencovsky - * - * This file is part of the C Macro Collections Libray. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * cmc_hashmultiset.h - * - * Creation Date: 10/04/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -/** - * HashMultiSet - * - * In mathematics, a multiset is a modification of the concept of a set that, - * unlike a set, allows for multiple instances for each of its elements. The - * positive integer number of instances, given for each element is called the - * multiplicity of this element in the multiset. A multiSet also has a - * cardinality which equals the sum of the multiplicities of its elements. - * - * Implementation - * - * In this implementation, the values are stored in a flat hashtable and are - * mapped to their multiplicity. - */ - -#ifndef CMC_CMC_HASHMULTISET_H -#define CMC_CMC_HASHMULTISET_H - -/* ------------------------------------------------------------------------- - * Core functionalities of the C Macro Collections Library - * ------------------------------------------------------------------------- */ -#include "cor_core.h" - -/* ------------------------------------------------------------------------- - * Hashtable Implementation - * ------------------------------------------------------------------------- */ -#include "cor_hashtable.h" - -/** - * Core HashMultiSet implementation - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_CMC_HASHMULTISET_CORE(ACCESS, FILE, PARAMS) \ - CMC_(CMC_(CMC_CMC_HASHMULTISET_CORE_, ACCESS), CMC_(_, FILE))(PARAMS) - -/* PRIVATE or PUBLIC solver */ -#define CMC_CMC_HASHMULTISET_CORE_PUBLIC_HEADER(PARAMS) \ - CMC_CMC_HASHMULTISET_CORE_STRUCT(PARAMS) \ - CMC_CMC_HASHMULTISET_CORE_HEADER(PARAMS) - -#define CMC_CMC_HASHMULTISET_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_HASHMULTISET_CORE_SOURCE(PARAMS) - -#define CMC_CMC_HASHMULTISET_CORE_PRIVATE_HEADER(PARAMS) \ - struct CMC_PARAM_SNAME(PARAMS); \ - struct CMC_DEF_ENTRY(CMC_PARAM_SNAME(PARAMS)); \ - CMC_CMC_HASHMULTISET_CORE_HEADER(PARAMS) - -#define CMC_CMC_HASHMULTISET_CORE_PRIVATE_SOURCE(PARAMS) \ - CMC_CMC_HASHMULTISET_CORE_STRUCT(PARAMS) \ - CMC_CMC_HASHMULTISET_CORE_SOURCE(PARAMS) - -/* Lowest level API */ -#define CMC_CMC_HASHMULTISET_CORE_STRUCT(PARAMS) \ - CMC_CMC_HASHMULTISET_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_CMC_HASHMULTISET_CORE_HEADER(PARAMS) \ - CMC_CMC_HASHMULTISET_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_CMC_HASHMULTISET_CORE_SOURCE(PARAMS) \ - CMC_CMC_HASHMULTISET_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -/* ------------------------------------------------------------------------- - * Struct - * ------------------------------------------------------------------------- */ -#define CMC_CMC_HASHMULTISET_CORE_STRUCT_(PFX, SNAME, V) \ -\ - /* HashMultiset Structure */ \ - struct SNAME \ - { \ - /* Array of Entries */ \ - struct CMC_DEF_ENTRY(SNAME) * buffer; \ -\ - /* Current Array Capcity */ \ - size_t capacity; \ -\ - /* Current amount of unique elements */ \ - size_t count; \ -\ - /* Total amount of elements taking into account their multiplicity */ \ - size_t cardinality; \ -\ - /* Load factor in range (0.0, 1.0) */ \ - double load; \ -\ - /* Flags indicating errors or success */ \ - int flag; \ -\ - /* Key function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ -\ - /* Custom allocation functions */ \ - struct CMC_ALLOC_NODE_NAME *alloc; \ -\ - /* Custom callback functions */ \ - CMC_CALLBACKS_DECL; \ - }; \ -\ - struct CMC_DEF_ENTRY(SNAME) \ - { \ - /* Entry element */ \ - V value; \ -\ - /* The element's multiplicity */ \ - size_t multiplicity; \ -\ - /* The distance of this node to its original position, used by */ \ - /* robin-hood hashing */ \ - size_t dist; \ -\ - /* The sate of this node (DELETED, EMPTY, FILLED) */ \ - enum cmc_entry_state state; \ - }; - -/* ------------------------------------------------------------------------- - * Header - * ------------------------------------------------------------------------- */ -#define CMC_CMC_HASHMULTISET_CORE_HEADER_(PFX, SNAME, V) \ -\ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(V); \ -\ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(V); \ -\ - /* To string function */ \ - CMC_DEF_FTAB_STR(V); \ -\ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(V); \ -\ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(V); \ -\ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(V); \ - }; \ -\ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks); \ - void CMC_(PFX, _clear)(struct SNAME * _set_); \ - void CMC_(PFX, _free)(struct SNAME * _set_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _set_, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _insert)(struct SNAME * _set_, V value); \ - bool CMC_(PFX, _insert_many)(struct SNAME * _set_, V value, size_t count); \ - bool CMC_(PFX, _update)(struct SNAME * _set_, V value, size_t multiplicity); \ - bool CMC_(PFX, _remove)(struct SNAME * _set_, V value); \ - size_t CMC_(PFX, _remove_all)(struct SNAME * _set_, V value); \ - /* Element Access */ \ - bool CMC_(PFX, _max)(struct SNAME * _set_, V * value); \ - bool CMC_(PFX, _min)(struct SNAME * _set_, V * value); \ - size_t CMC_(PFX, _multiplicity_of)(struct SNAME * _set_, V value); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _set_, V value); \ - bool CMC_(PFX, _empty)(struct SNAME * _set_); \ - bool CMC_(PFX, _full)(struct SNAME * _set_); \ - size_t CMC_(PFX, _count)(struct SNAME * _set_); \ - size_t CMC_(PFX, _cardinality)(struct SNAME * _set_); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _set_); \ - double CMC_(PFX, _load)(struct SNAME * _set_); \ - int CMC_(PFX, _flag)(struct SNAME * _set_); \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _set_, size_t capacity); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_); \ - bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_); - -/* ------------------------------------------------------------------------- - * Source - * ------------------------------------------------------------------------- */ -#define CMC_CMC_HASHMULTISET_CORE_SOURCE_(PFX, SNAME, V) \ -\ - /* Implementation Detail Functions */ \ - static size_t CMC_(PFX, _impl_multiplicity_of)(struct SNAME * _set_, V value); \ - static struct CMC_DEF_ENTRY(SNAME) * \ - CMC_(PFX, _impl_insert_and_return)(struct SNAME * _set_, V value, bool *new_node); \ - static struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_get_entry)(struct SNAME * _set_, V value); \ - static size_t CMC_(PFX, _impl_calculate_size)(size_t required); \ -\ - struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - return CMC_(PFX, _new_custom)(capacity, load, f_val, NULL, NULL); \ - } \ -\ - struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - if (capacity == 0 || load <= 0 || load >= 1) \ - return NULL; \ -\ - /* Prevent integer overflow */ \ - if (capacity >= UINTMAX_MAX * load) \ - return NULL; \ -\ - if (!f_val) \ - return NULL; \ -\ - size_t real_capacity = CMC_(PFX, _impl_calculate_size)(capacity / load); \ -\ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ -\ - struct SNAME *_set_ = alloc->malloc(sizeof(struct SNAME)); \ -\ - if (!_set_) \ - return NULL; \ -\ - _set_->buffer = alloc->calloc(real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME))); \ -\ - if (!_set_->buffer) \ - { \ - alloc->free(_set_); \ - return NULL; \ - } \ -\ - _set_->count = 0; \ - _set_->cardinality = 0; \ - _set_->capacity = real_capacity; \ - _set_->load = load; \ - _set_->flag = CMC_FLAG_OK; \ - _set_->f_val = f_val; \ - _set_->alloc = alloc; \ - CMC_CALLBACKS_ASSIGN(_set_, callbacks); \ -\ - return _set_; \ - } \ -\ - void CMC_(PFX, _clear)(struct SNAME * _set_) \ - { \ - if (_set_->f_val->free) \ - { \ - for (size_t i = 0; i < _set_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \ -\ - if (entry->state == CMC_ES_FILLED) \ - { \ - _set_->f_val->free(entry->value); \ - } \ - } \ - } \ -\ - memset(_set_->buffer, 0, sizeof(struct CMC_DEF_ENTRY(SNAME)) * _set_->capacity); \ -\ - _set_->count = 0; \ - _set_->flag = CMC_FLAG_OK; \ - } \ -\ - void CMC_(PFX, _free)(struct SNAME * _set_) \ - { \ - if (_set_->f_val->free) \ - { \ - for (size_t i = 0; i < _set_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \ -\ - if (entry->state == CMC_ES_FILLED) \ - { \ - _set_->f_val->free(entry->value); \ - } \ - } \ - } \ -\ - _set_->alloc->free(_set_->buffer); \ - _set_->alloc->free(_set_); \ - } \ -\ - void CMC_(PFX, _customize)(struct SNAME * _set_, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - if (!alloc) \ - _set_->alloc = &cmc_alloc_node_default; \ - else \ - _set_->alloc = alloc; \ -\ - CMC_CALLBACKS_ASSIGN(_set_, callbacks); \ -\ - _set_->flag = CMC_FLAG_OK; \ - } \ -\ - bool CMC_(PFX, _insert)(struct SNAME * _set_, V value) \ - { \ - bool new_node; \ -\ - struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_insert_and_return)(_set_, value, &new_node); \ -\ - if (!entry) \ - { \ - _set_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ -\ - if (!new_node) \ - entry->multiplicity++; \ -\ - _set_->cardinality++; \ - _set_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_set_, create); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _insert_many)(struct SNAME * _set_, V value, size_t count) \ - { \ - if (count == 0) \ - goto success; \ -\ - bool new_node; \ -\ - struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_insert_and_return)(_set_, value, &new_node); \ -\ - if (!entry) \ - { \ - _set_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ -\ - if (new_node) \ - entry->multiplicity = count; \ - else \ - entry->multiplicity += count; \ -\ - _set_->cardinality += count; \ -\ - success: \ -\ - _set_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_set_, create); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _update)(struct SNAME * _set_, V value, size_t multiplicity) \ - { \ - if (multiplicity == 0) \ - { \ - /* Effectively delete the entry */ \ - struct CMC_DEF_ENTRY(SNAME) *result = CMC_(PFX, _impl_get_entry)(_set_, value); \ -\ - if (!result) \ - /* If no entry was found then its multiplicity is already 0 */ \ - goto success; \ -\ - _set_->count--; \ - _set_->cardinality -= result->multiplicity; \ -\ - result->value = (V){ 0 }; \ - result->multiplicity = 0; \ - result->dist = 0; \ - result->state = CMC_ES_DELETED; \ -\ - goto success; \ - } \ -\ - bool new_node; \ -\ - struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_insert_and_return)(_set_, value, &new_node); \ -\ - if (!entry) \ - return false; \ -\ - if (new_node) \ - _set_->cardinality++; \ -\ - _set_->cardinality = (_set_->cardinality - entry->multiplicity) + multiplicity; \ -\ - entry->multiplicity = multiplicity; \ -\ - success: \ -\ - _set_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_set_, update); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _remove)(struct SNAME * _set_, V value) \ - { \ - if (CMC_(PFX, _empty)(_set_)) \ - { \ - _set_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - struct CMC_DEF_ENTRY(SNAME) *result = CMC_(PFX, _impl_get_entry)(_set_, value); \ -\ - if (!result) \ - { \ - _set_->flag = CMC_FLAG_NOT_FOUND; \ - return false; \ - } \ -\ - if (result->multiplicity > 1) \ - result->multiplicity--; \ - else \ - { \ - result->value = (V){ 0 }; \ - result->multiplicity = 0; \ - result->dist = 0; \ - result->state = CMC_ES_DELETED; \ -\ - _set_->count--; \ - } \ -\ - _set_->cardinality--; \ - _set_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_set_, delete); \ -\ - return true; \ - } \ -\ - size_t CMC_(PFX, _remove_all)(struct SNAME * _set_, V value) \ - { \ - if (CMC_(PFX, _empty)(_set_)) \ - { \ - _set_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - struct CMC_DEF_ENTRY(SNAME) *result = CMC_(PFX, _impl_get_entry)(_set_, value); \ -\ - if (!result) \ - { \ - _set_->flag = CMC_FLAG_NOT_FOUND; \ - return 0; \ - } \ -\ - size_t removed = result->multiplicity; \ -\ - result->value = (V){ 0 }; \ - result->multiplicity = 0; \ - result->dist = 0; \ - result->state = CMC_ES_DELETED; \ -\ - _set_->count--; \ - _set_->cardinality -= removed; \ - _set_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_set_, delete); \ -\ - return removed; \ - } \ -\ - bool CMC_(PFX, _max)(struct SNAME * _set_, V * value) \ - { \ - if (CMC_(PFX, _empty)(_set_)) \ - { \ - _set_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - bool first = true; \ - V max_val = (V){ 0 }; \ -\ - for (size_t i = 0; i < _set_->capacity; i++) \ - { \ - if (_set_->buffer[i].state == CMC_ES_FILLED) \ - { \ - if (first) \ - { \ - max_val = _set_->buffer[i].value; \ - first = false; \ - } \ - else if (_set_->f_val->cmp(_set_->buffer[i].value, max_val) > 0) \ - { \ - max_val = _set_->buffer[i].value; \ - } \ - } \ - } \ -\ - if (value) \ - *value = max_val; \ -\ - _set_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_set_, read); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _min)(struct SNAME * _set_, V * value) \ - { \ - if (CMC_(PFX, _empty)(_set_)) \ - { \ - _set_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - bool first = true; \ - V min_val = (V){ 0 }; \ -\ - for (size_t i = 0; i < _set_->capacity; i++) \ - { \ - if (_set_->buffer[i].state == CMC_ES_FILLED) \ - { \ - if (first) \ - { \ - min_val = _set_->buffer[i].value; \ - first = false; \ - } \ - else if (_set_->f_val->cmp(_set_->buffer[i].value, min_val) < 0) \ - { \ - min_val = _set_->buffer[i].value; \ - } \ - } \ - } \ -\ - if (value) \ - *value = min_val; \ -\ - _set_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_set_, read); \ -\ - return true; \ - } \ -\ - size_t CMC_(PFX, _multiplicity_of)(struct SNAME * _set_, V value) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_set_, value); \ -\ - _set_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_set_, read); \ -\ - if (!entry) \ - return 0; \ -\ - return entry->multiplicity; \ - } \ -\ - bool CMC_(PFX, _contains)(struct SNAME * _set_, V value) \ - { \ - _set_->flag = CMC_FLAG_OK; \ -\ - bool result = CMC_(PFX, _impl_get_entry)(_set_, value) != NULL; \ -\ - CMC_CALLBACKS_CALL(_set_, read); \ -\ - return result; \ - } \ -\ - bool CMC_(PFX, _empty)(struct SNAME * _set_) \ - { \ - return _set_->count == 0; \ - } \ -\ - bool CMC_(PFX, _full)(struct SNAME * _set_) \ - { \ - return (double)_set_->capacity * _set_->load <= (double)_set_->count; \ - } \ -\ - size_t CMC_(PFX, _count)(struct SNAME * _set_) \ - { \ - return _set_->count; \ - } \ -\ - size_t CMC_(PFX, _cardinality)(struct SNAME * _set_) \ - { \ - return _set_->cardinality; \ - } \ -\ - size_t CMC_(PFX, _capacity)(struct SNAME * _set_) \ - { \ - return _set_->capacity; \ - } \ -\ - double CMC_(PFX, _load)(struct SNAME * _set_) \ - { \ - return _set_->load; \ - } \ -\ - int CMC_(PFX, _flag)(struct SNAME * _set_) \ - { \ - return _set_->flag; \ - } \ -\ - bool CMC_(PFX, _resize)(struct SNAME * _set_, size_t capacity) \ - { \ - _set_->flag = CMC_FLAG_OK; \ -\ - if (_set_->capacity == capacity) \ - goto success; \ -\ - if (_set_->capacity > capacity / _set_->load) \ - goto success; \ -\ - /* Prevent integer overflow */ \ - if (capacity >= UINTMAX_MAX * _set_->load) \ - { \ - _set_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ -\ - /* Calculate required capacity based on the prime numbers */ \ - size_t theoretical_size = CMC_(PFX, _impl_calculate_size)(capacity); \ -\ - /* Not possible to shrink with current available prime numbers */ \ - if (theoretical_size < _set_->count / _set_->load) \ - { \ - _set_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ -\ - /* No callbacks since _new_set_ is just a temporary hashtable */ \ - struct SNAME *_new_set_ = CMC_(PFX, _new_custom)(capacity, _set_->load, _set_->f_val, _set_->alloc, NULL); \ -\ - if (!_new_set_) \ - { \ - _set_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ -\ - for (size_t i = 0; i < _set_->capacity; i++) \ - { \ - if (_set_->buffer[i].state == CMC_ES_FILLED) \ - { \ - V value = _set_->buffer[i].value; \ - size_t multiplicity = _set_->buffer[i].multiplicity; \ -\ - /* TODO check this for possible errors where entry == NULL */ \ - struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_insert_and_return)(_new_set_, value, NULL); \ -\ - entry->multiplicity = multiplicity; \ - /* Setting cardinality not required, _new_set_ is temporary */ \ - } \ - } \ -\ - if (_set_->count != _new_set_->count) \ - { \ - CMC_(PFX, _free)(_new_set_); \ -\ - _set_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ -\ - struct CMC_DEF_ENTRY(SNAME) *tmp_b = _set_->buffer; \ - _set_->buffer = _new_set_->buffer; \ - _new_set_->buffer = tmp_b; \ -\ - size_t tmp_c = _set_->capacity; \ - _set_->capacity = _new_set_->capacity; \ - _new_set_->capacity = tmp_c; \ -\ - /* Prevent the set from freeing the data */ \ - _new_set_->f_val = &(struct CMC_DEF_FVAL(SNAME)){ NULL }; \ -\ - CMC_(PFX, _free)(_new_set_); \ -\ - success: \ -\ - CMC_CALLBACKS_CALL(_set_, resize); \ -\ - return true; \ - } \ -\ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_) \ - { \ - struct SNAME *result = \ - CMC_(PFX, _new_custom)(_set_->capacity * _set_->load, _set_->load, _set_->f_val, _set_->alloc, NULL); \ -\ - if (!result) \ - { \ - _set_->flag = CMC_FLAG_ERROR; \ - return NULL; \ - } \ -\ - CMC_CALLBACKS_ASSIGN(result, _set_->callbacks); \ -\ - if (_set_->f_val->cpy) \ - { \ - for (size_t i = 0; i < _set_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *scan = &(_set_->buffer[i]); \ -\ - if (scan->state != CMC_ES_EMPTY) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *target = &(result->buffer[i]); \ -\ - if (scan->state == CMC_ES_DELETED) \ - target->state = CMC_ES_DELETED; \ - else \ - { \ - target->state = scan->state; \ - target->dist = scan->dist; \ - target->multiplicity = scan->multiplicity; \ -\ - target->value = _set_->f_val->cpy(scan->value); \ - } \ - } \ - } \ - } \ - else \ - memcpy(result->buffer, _set_->buffer, sizeof(struct CMC_DEF_ENTRY(SNAME)) * _set_->capacity); \ -\ - result->count = _set_->count; \ - result->cardinality = _set_->cardinality; \ -\ - _set_->flag = CMC_FLAG_OK; \ -\ - return result; \ - } \ -\ - bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - _set1_->flag = CMC_FLAG_OK; \ - _set2_->flag = CMC_FLAG_OK; \ -\ - if (_set1_->count != _set2_->count) \ - return false; \ -\ - if (_set1_->cardinality != _set2_->cardinality) \ - return false; \ -\ - if (_set1_->count == 0) \ - return true; \ -\ - /* Optimize loop using the smallest hashtable */ \ - struct SNAME *_set_a_; \ - struct SNAME *_set_b_; \ -\ - _set_a_ = _set1_->capacity < _set2_->capacity ? _set1_ : _set2_; \ - _set_b_ = _set_a_ == _set1_ ? _set2_ : _set1_; \ -\ - for (size_t i = 0; i < _set_a_->capacity; i++) \ - { \ - if (_set_a_->buffer[i].state == CMC_ES_FILLED) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry_a = &(_set_a_->buffer[i]); \ - struct CMC_DEF_ENTRY(SNAME) *entry_b = CMC_(PFX, _impl_get_entry)(_set_b_, entry_a->value); \ -\ - if (!entry_b) \ - return false; \ -\ - if (entry_a->multiplicity != entry_b->multiplicity) \ - return false; \ - } \ - } \ -\ - return true; \ - } \ -\ - static size_t CMC_(PFX, _impl_multiplicity_of)(struct SNAME * _set_, V value) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_set_, value); \ -\ - if (!entry) \ - return 0; \ -\ - return entry->multiplicity; \ - } \ -\ - static struct CMC_DEF_ENTRY(SNAME) * \ - CMC_(PFX, _impl_insert_and_return)(struct SNAME * _set_, V value, bool *new_node) \ - { \ - /* If the entry already exists simply return it as we might do */ \ - /* something with it. This function only guarantees that there is */ \ - /* a valid entry for a given value */ \ -\ - if (new_node) \ - *new_node = false; \ -\ - struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_set_, value); \ -\ - if (entry != NULL) \ - return entry; \ -\ - if (new_node) \ - *new_node = true; \ -\ - if (CMC_(PFX, _full)(_set_)) \ - { \ - if (!CMC_(PFX, _resize)(_set_, _set_->capacity + 1)) \ - return NULL; \ - } \ -\ - size_t hash = _set_->f_val->hash(value); \ - size_t original_pos = hash % _set_->capacity; \ - size_t pos = original_pos; \ - /* Current multiplicity. Might change due to robin hood hashing */ \ - size_t curr_mul = 1; \ -\ - struct CMC_DEF_ENTRY(SNAME) *target = &(_set_->buffer[pos]); \ - struct CMC_DEF_ENTRY(SNAME) *to_return = NULL; \ -\ - if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) \ - { \ - target->value = value; \ - target->multiplicity = curr_mul; \ - target->dist = pos - original_pos; \ - target->state = CMC_ES_FILLED; \ -\ - to_return = target; \ - } \ - else \ - { \ - while (true) \ - { \ - pos++; \ - target = &(_set_->buffer[pos % _set_->capacity]); \ -\ - if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) \ - { \ - target->value = value; \ - target->multiplicity = curr_mul; \ - target->dist = pos - original_pos; \ - target->state = CMC_ES_FILLED; \ -\ - if (!to_return) \ - to_return = target; \ -\ - break; \ - } \ - else if (target->dist < pos - original_pos) \ - { \ - /* Swap everything */ \ - V tmp = target->value; \ - size_t tmp_dist = target->dist; \ - size_t tmp_mul = target->multiplicity; \ -\ - target->value = value; \ - target->dist = pos - original_pos; \ - target->multiplicity = curr_mul; \ -\ - value = tmp; \ - original_pos = pos - tmp_dist; \ - curr_mul = tmp_mul; \ -\ - if (!to_return) \ - to_return = target; \ - } \ - } \ - } \ -\ - _set_->count++; \ -\ - return to_return; \ - } \ -\ - static struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_get_entry)(struct SNAME * _set_, V value) \ - { \ - size_t hash = _set_->f_val->hash(value); \ - size_t pos = hash % _set_->capacity; \ -\ - struct CMC_DEF_ENTRY(SNAME) *target = &(_set_->buffer[pos]); \ -\ - while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED) \ - { \ - if (_set_->f_val->cmp(target->value, value) == 0) \ - return target; \ -\ - pos++; \ - target = &(_set_->buffer[pos % _set_->capacity]); \ - } \ -\ - return NULL; \ - } \ -\ - static size_t CMC_(PFX, _impl_calculate_size)(size_t required) \ - { \ - const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); \ -\ - if (cmc_hashtable_primes[count - 1] < required) \ - return required; \ -\ - size_t i = 0; \ - while (cmc_hashtable_primes[i] < required) \ - i++; \ -\ - return cmc_hashtable_primes[i]; \ - } - -#endif /* CMC_CMC_HASHMULTISET_H */ diff --git a/src/cmc_hashset.h b/src/cmc_hashset.h deleted file mode 100644 index 8965fb8..0000000 --- a/src/cmc_hashset.h +++ /dev/null @@ -1,694 +0,0 @@ -/** - * Copyright (c) 2019 Leonardo Vencovsky - * - * This file is part of the C Macro Collections Libray. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * cmc_hashset.h - * - * Creation Date: 01/04/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -/** - * HashSet - * - * A HashSet is an implementation of a Set with unique keys. The keys are not - * sorted. It is implemented as a flat hashtable with linear probing and robin - * hood hashing. - */ - -#ifndef CMC_CMC_HASHSET_H -#define CMC_CMC_HASHSET_H - -/* ------------------------------------------------------------------------- - * Core functionalities of the C Macro Collections Library - * ------------------------------------------------------------------------- */ -#include "cor_core.h" - -/* ------------------------------------------------------------------------- - * Hashtable Implementation - * ------------------------------------------------------------------------- */ -#include "cor_hashtable.h" - -/** - * Core HashSet implementation - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_CMC_HASHSET_CORE(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_CMC_HASHSET_CORE_, ACCESS), CMC_(_, FILE))(PARAMS) - -/* PRIVATE or PUBLIC solver */ -#define CMC_CMC_HASHSET_CORE_PUBLIC_HEADER(PARAMS) \ - CMC_CMC_HASHSET_CORE_STRUCT(PARAMS) \ - CMC_CMC_HASHSET_CORE_HEADER(PARAMS) - -#define CMC_CMC_HASHSET_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_HASHSET_CORE_SOURCE(PARAMS) - -#define CMC_CMC_HASHSET_CORE_PRIVATE_HEADER(PARAMS) \ - struct CMC_PARAM_SNAME(PARAMS); \ - struct CMC_DEF_ENTRY(CMC_PARAM_SNAME(PARAMS)); \ - CMC_CMC_HASHSET_CORE_HEADER(PARAMS) - -#define CMC_CMC_HASHSET_CORE_PRIVATE_SOURCE(PARAMS) \ - CMC_CMC_HASHSET_CORE_STRUCT(PARAMS) \ - CMC_CMC_HASHSET_CORE_SOURCE(PARAMS) - -/* Lowest level API */ -#define CMC_CMC_HASHSET_CORE_STRUCT(PARAMS) \ - CMC_CMC_HASHSET_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_CMC_HASHSET_CORE_HEADER(PARAMS) \ - CMC_CMC_HASHSET_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_CMC_HASHSET_CORE_SOURCE(PARAMS) \ - CMC_CMC_HASHSET_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -/* ------------------------------------------------------------------------- - * Struct - * ------------------------------------------------------------------------- */ -#define CMC_CMC_HASHSET_CORE_STRUCT_(PFX, SNAME, V) \ -\ - /* Hashset Structure */ \ - struct SNAME \ - { \ - /* Array of Entries */ \ - struct CMC_DEF_ENTRY(SNAME) * buffer; \ -\ - /* Current Array Capcity */ \ - size_t capacity; \ -\ - /* Current amount of elements */ \ - size_t count; \ -\ - /* Load factor in range (0.0, 1.0) */ \ - double load; \ -\ - /* Flags indicating errors or success */ \ - int flag; \ -\ - /* Value function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ -\ - /* Custom allocation functions */ \ - struct CMC_ALLOC_NODE_NAME *alloc; \ -\ - /* Custom callback functions */ \ - CMC_CALLBACKS_DECL; \ - }; \ -\ - struct CMC_DEF_ENTRY(SNAME) \ - { \ - /* Entry value */ \ - V value; \ -\ - /* The distance of this node to its original position, used by */ \ - /* robin-hood hashing */ \ - size_t dist; \ -\ - /* The sate of this node (DELETED, EMPTY, FILLED) */ \ - enum cmc_entry_state state; \ - }; - -/* ------------------------------------------------------------------------- - * Header - * ------------------------------------------------------------------------- */ -#define CMC_CMC_HASHSET_CORE_HEADER_(PFX, SNAME, V) \ -\ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(V); \ -\ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(V); \ -\ - /* To string function */ \ - CMC_DEF_FTAB_STR(V); \ -\ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(V); \ -\ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(V); \ -\ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(V); \ - }; \ -\ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks); \ - void CMC_(PFX, _clear)(struct SNAME * _set_); \ - void CMC_(PFX, _free)(struct SNAME * _set_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _set_, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _insert)(struct SNAME * _set_, V value); \ - bool CMC_(PFX, _remove)(struct SNAME * _set_, V value); \ - /* Element Access */ \ - bool CMC_(PFX, _max)(struct SNAME * _set_, V * value); \ - bool CMC_(PFX, _min)(struct SNAME * _set_, V * value); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _set_, V value); \ - bool CMC_(PFX, _empty)(struct SNAME * _set_); \ - bool CMC_(PFX, _full)(struct SNAME * _set_); \ - size_t CMC_(PFX, _count)(struct SNAME * _set_); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _set_); \ - double CMC_(PFX, _load)(struct SNAME * _set_); \ - int CMC_(PFX, _flag)(struct SNAME * _set_); \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _set_, size_t capacity); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_); \ - bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_); - -/* ------------------------------------------------------------------------- - * Source - * ------------------------------------------------------------------------- */ -#define CMC_CMC_HASHSET_CORE_SOURCE_(PFX, SNAME, V) \ -\ - /* Implementation Detail Functions */ \ - static struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_get_entry)(struct SNAME * _set_, V value); \ - static size_t CMC_(PFX, _impl_calculate_size)(size_t required); \ -\ - struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - return CMC_(PFX, _new_custom)(capacity, load, f_val, NULL, NULL); \ - } \ -\ - struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - if (capacity == 0 || load <= 0 || load >= 1) \ - return NULL; \ -\ - /* Prevent integer overflow */ \ - if (capacity >= UINTMAX_MAX * load) \ - return NULL; \ -\ - if (!f_val) \ - return NULL; \ -\ - size_t real_capacity = CMC_(PFX, _impl_calculate_size)(capacity / load); \ -\ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ -\ - struct SNAME *_set_ = alloc->malloc(sizeof(struct SNAME)); \ -\ - if (!_set_) \ - return NULL; \ -\ - _set_->buffer = alloc->calloc(real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME))); \ -\ - if (!_set_->buffer) \ - { \ - alloc->free(_set_); \ - return NULL; \ - } \ -\ - _set_->count = 0; \ - _set_->capacity = real_capacity; \ - _set_->load = load; \ - _set_->flag = CMC_FLAG_OK; \ - _set_->f_val = f_val; \ - _set_->alloc = alloc; \ - CMC_CALLBACKS_ASSIGN(_set_, callbacks); \ -\ - return _set_; \ - } \ -\ - void CMC_(PFX, _clear)(struct SNAME * _set_) \ - { \ - if (_set_->f_val->free) \ - { \ - for (size_t i = 0; i < _set_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \ -\ - if (entry->state == CMC_ES_FILLED) \ - { \ - _set_->f_val->free(entry->value); \ - } \ - } \ - } \ -\ - memset(_set_->buffer, 0, sizeof(struct CMC_DEF_ENTRY(SNAME)) * _set_->capacity); \ -\ - _set_->count = 0; \ - _set_->flag = CMC_FLAG_OK; \ - } \ -\ - void CMC_(PFX, _free)(struct SNAME * _set_) \ - { \ - if (_set_->f_val->free) \ - { \ - for (size_t i = 0; i < _set_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \ -\ - if (entry->state == CMC_ES_FILLED) \ - { \ - _set_->f_val->free(entry->value); \ - } \ - } \ - } \ -\ - _set_->alloc->free(_set_->buffer); \ - _set_->alloc->free(_set_); \ - } \ -\ - void CMC_(PFX, _customize)(struct SNAME * _set_, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - if (!alloc) \ - _set_->alloc = &cmc_alloc_node_default; \ - else \ - _set_->alloc = alloc; \ -\ - CMC_CALLBACKS_ASSIGN(_set_, callbacks); \ -\ - _set_->flag = CMC_FLAG_OK; \ - } \ -\ - bool CMC_(PFX, _insert)(struct SNAME * _set_, V value) \ - { \ - if (CMC_(PFX, _full)(_set_)) \ - { \ - if (!CMC_(PFX, _resize)(_set_, _set_->capacity + 1)) \ - return false; \ - } \ -\ - if (CMC_(PFX, _impl_get_entry)(_set_, value) != NULL) \ - { \ - _set_->flag = CMC_FLAG_DUPLICATE; \ - return false; \ - } \ -\ - size_t hash = _set_->f_val->hash(value); \ - size_t original_pos = hash % _set_->capacity; \ - size_t pos = original_pos; \ -\ - struct CMC_DEF_ENTRY(SNAME) *target = &(_set_->buffer[pos]); \ -\ - if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) \ - { \ - target->value = value; \ - target->dist = 0; \ - target->state = CMC_ES_FILLED; \ - } \ - else \ - { \ - while (true) \ - { \ - pos++; \ - target = &(_set_->buffer[pos % _set_->capacity]); \ -\ - if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) \ - { \ - target->value = value; \ - target->dist = pos - original_pos; \ - target->state = CMC_ES_FILLED; \ -\ - break; \ - } \ - else if (target->dist < pos - original_pos) \ - { \ - V tmp = target->value; \ - size_t tmp_dist = target->dist; \ -\ - target->value = value; \ - target->dist = pos - original_pos; \ -\ - value = tmp; \ - original_pos = pos - tmp_dist; \ - } \ - } \ - } \ -\ - _set_->count++; \ - _set_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_set_, create); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _remove)(struct SNAME * _set_, V value) \ - { \ - if (CMC_(PFX, _empty)(_set_)) \ - { \ - _set_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - struct CMC_DEF_ENTRY(SNAME) *result = CMC_(PFX, _impl_get_entry)(_set_, value); \ -\ - if (result == NULL) \ - { \ - _set_->flag = CMC_FLAG_NOT_FOUND; \ - return false; \ - } \ -\ - result->value = (V){ 0 }; \ - result->dist = 0; \ - result->state = CMC_ES_DELETED; \ -\ - _set_->count--; \ - _set_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_set_, delete); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _max)(struct SNAME * _set_, V * value) \ - { \ - if (CMC_(PFX, _empty)(_set_)) \ - { \ - _set_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - bool first = true; \ - V max_val = (V){ 0 }; \ -\ - for (size_t i = 0; i < _set_->capacity; i++) \ - { \ - if (_set_->buffer[i].state == CMC_ES_FILLED) \ - { \ - if (first) \ - { \ - max_val = _set_->buffer[i].value; \ - first = false; \ - } \ - else if (_set_->f_val->cmp(_set_->buffer[i].value, max_val) > 0) \ - { \ - max_val = _set_->buffer[i].value; \ - } \ - } \ - } \ -\ - if (value) \ - *value = max_val; \ -\ - _set_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_set_, read); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _min)(struct SNAME * _set_, V * value) \ - { \ - if (CMC_(PFX, _empty)(_set_)) \ - { \ - _set_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - bool first = true; \ - V min_val = (V){ 0 }; \ -\ - for (size_t i = 0; i < _set_->capacity; i++) \ - { \ - if (_set_->buffer[i].state == CMC_ES_FILLED) \ - { \ - if (first) \ - { \ - min_val = _set_->buffer[i].value; \ - first = false; \ - } \ - else if (_set_->f_val->cmp(_set_->buffer[i].value, min_val) < 0) \ - { \ - min_val = _set_->buffer[i].value; \ - } \ - } \ - } \ -\ - if (value) \ - *value = min_val; \ -\ - _set_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_set_, read); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _contains)(struct SNAME * _set_, V value) \ - { \ - _set_->flag = CMC_FLAG_OK; \ -\ - bool result = CMC_(PFX, _impl_get_entry)(_set_, value) != NULL; \ -\ - CMC_CALLBACKS_CALL(_set_, read); \ -\ - return result; \ - } \ -\ - bool CMC_(PFX, _empty)(struct SNAME * _set_) \ - { \ - return _set_->count == 0; \ - } \ -\ - bool CMC_(PFX, _full)(struct SNAME * _set_) \ - { \ - return (double)_set_->capacity * _set_->load <= (double)_set_->count; \ - } \ -\ - size_t CMC_(PFX, _count)(struct SNAME * _set_) \ - { \ - return _set_->count; \ - } \ -\ - size_t CMC_(PFX, _capacity)(struct SNAME * _set_) \ - { \ - return _set_->capacity; \ - } \ -\ - double CMC_(PFX, _load)(struct SNAME * _set_) \ - { \ - return _set_->load; \ - } \ -\ - int CMC_(PFX, _flag)(struct SNAME * _set_) \ - { \ - return _set_->flag; \ - } \ -\ - bool CMC_(PFX, _resize)(struct SNAME * _set_, size_t capacity) \ - { \ - _set_->flag = CMC_FLAG_OK; \ -\ - if (_set_->capacity == capacity) \ - goto success; \ -\ - if (_set_->capacity > capacity / _set_->load) \ - goto success; \ -\ - /* Prevent integer overflow */ \ - if (capacity >= UINTMAX_MAX * _set_->load) \ - { \ - _set_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ -\ - /* Calculate required capacity based on the prime numbers */ \ - size_t theoretical_size = CMC_(PFX, _impl_calculate_size)(capacity); \ -\ - /* Not possible to shrink with current available prime numbers */ \ - if (theoretical_size < _set_->count / _set_->load) \ - { \ - _set_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ -\ - /* No callbacks since _new_set_ is just a temporary hashtable */ \ - struct SNAME *_new_set_ = CMC_(PFX, _new_custom)(capacity, _set_->load, _set_->f_val, _set_->alloc, NULL); \ -\ - if (!_new_set_) \ - { \ - _set_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ -\ - for (size_t i = 0; i < _set_->capacity; i++) \ - { \ - if (_set_->buffer[i].state == CMC_ES_FILLED) \ - { \ - V value = _set_->buffer[i].value; \ -\ - /* TODO check this for possible errors */ \ - CMC_(PFX, _insert)(_new_set_, value); \ - } \ - } \ -\ - /* Unlikely */ \ - if (_set_->count != _new_set_->count) \ - { \ - CMC_(PFX, _free)(_new_set_); \ -\ - _set_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ -\ - struct CMC_DEF_ENTRY(SNAME) *tmp_b = _set_->buffer; \ - _set_->buffer = _new_set_->buffer; \ - _new_set_->buffer = tmp_b; \ -\ - size_t tmp_c = _set_->capacity; \ - _set_->capacity = _new_set_->capacity; \ - _new_set_->capacity = tmp_c; \ -\ - /* Prevent the set from freeing the data */ \ - _new_set_->f_val = &(struct CMC_DEF_FVAL(SNAME)){ NULL }; \ -\ - CMC_(PFX, _free)(_new_set_); \ -\ - success: \ -\ - CMC_CALLBACKS_CALL(_set_, resize); \ -\ - return true; \ - } \ -\ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_) \ - { \ - struct SNAME *result = \ - CMC_(PFX, _new_custom)(_set_->capacity * _set_->load, _set_->load, _set_->f_val, _set_->alloc, NULL); \ -\ - if (!result) \ - { \ - _set_->flag = CMC_FLAG_ERROR; \ - return NULL; \ - } \ -\ - CMC_CALLBACKS_ASSIGN(result, _set_->callbacks); \ -\ - if (_set_->f_val->cpy) \ - { \ - for (size_t i = 0; i < _set_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *scan = &(_set_->buffer[i]); \ -\ - if (scan->state != CMC_ES_EMPTY) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *target = &(result->buffer[i]); \ -\ - if (scan->state == CMC_ES_DELETED) \ - target->state = CMC_ES_DELETED; \ - else \ - { \ - target->state = scan->state; \ - target->dist = scan->dist; \ -\ - target->value = _set_->f_val->cpy(scan->value); \ - } \ - } \ - } \ - } \ - else \ - memcpy(result->buffer, _set_->buffer, sizeof(struct CMC_DEF_ENTRY(SNAME)) * _set_->capacity); \ -\ - result->count = _set_->count; \ -\ - _set_->flag = CMC_FLAG_OK; \ -\ - return result; \ - } \ -\ - bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - _set1_->flag = CMC_FLAG_OK; \ - _set2_->flag = CMC_FLAG_OK; \ -\ - if (_set1_->count != _set2_->count) \ - return false; \ -\ - /* Optimize loop using the smallest hashtable */ \ - struct SNAME *_set_a_; \ - struct SNAME *_set_b_; \ -\ - _set_a_ = _set1_->capacity < _set2_->capacity ? _set1_ : _set2_; \ - _set_b_ = _set_a_ == _set1_ ? _set2_ : _set1_; \ -\ - for (size_t i = 0; i < _set_a_->capacity; i++) \ - { \ - if (_set_a_->buffer[i].state == CMC_ES_FILLED) \ - { \ -\ - if (!CMC_(PFX, _impl_get_entry)(_set_b_, _set_a_->buffer[i].value)) \ - return false; \ - } \ - } \ -\ - return true; \ - } \ -\ - static struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_get_entry)(struct SNAME * _set_, V value) \ - { \ - size_t hash = _set_->f_val->hash(value); \ - size_t pos = hash % _set_->capacity; \ -\ - struct CMC_DEF_ENTRY(SNAME) *target = &(_set_->buffer[pos]); \ -\ - while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED) \ - { \ - if (_set_->f_val->cmp(target->value, value) == 0) \ - return target; \ -\ - pos++; \ - target = &(_set_->buffer[pos % _set_->capacity]); \ - } \ -\ - return NULL; \ - } \ -\ - static size_t CMC_(PFX, _impl_calculate_size)(size_t required) \ - { \ - const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); \ -\ - if (cmc_hashtable_primes[count - 1] < required) \ - return required; \ -\ - size_t i = 0; \ - while (cmc_hashtable_primes[i] < required) \ - i++; \ -\ - return cmc_hashtable_primes[i]; \ - } - -#endif /* CMC_CMC_HASHSET_H */ diff --git a/src/cmc_heap.h b/src/cmc_heap.h deleted file mode 100644 index 4a0e1d0..0000000 --- a/src/cmc_heap.h +++ /dev/null @@ -1,533 +0,0 @@ -/** - * Copyright (c) 2019 Leonardo Vencovsky - * - * This file is part of the C Macro Collections Libray. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * cmc_heap.h - * - * Creation Date: 25/03/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -/** - * Heap - * - * The Heap is a specialized tree-based data structure which is essentially a - * complete tree that satisfies the heap property: - * - MaxHeap: - * - The root node is the greatest element of the unique set of keys. - * - A node key is always greater than or equal to its children keys. - * - Minheap: - * - The root node is the smallest element of the unique set of keys. - * - A node Key is always greater than or equal to its children keys. - * - * The heap is mostly used to implement priority queues. Sometimes it can also - * be used to sort elements. There are three main functions: - * - insert : Adds an element to the heap - * - remove_(min/max): Removes the min/max element from the heap - * - min/max : Accesses the min/max element from the heap - */ - -#ifndef CMC_CMC_HEAP_H -#define CMC_CMC_HEAP_H - -/* ------------------------------------------------------------------------- - * Core functionalities of the C Macro Collections Library - * ------------------------------------------------------------------------- */ -#include "cor_core.h" - -/* ------------------------------------------------------------------------- - * Heap Implementation - * ------------------------------------------------------------------------- */ -#include "cor_heap.h" - -/** - * Core Heap implementation - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_CMC_HEAP_CORE(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_CMC_HEAP_CORE_, ACCESS), CMC_(_, FILE))(PARAMS) - -/* PRIVATE or PUBLIC solver */ -#define CMC_CMC_HEAP_CORE_PUBLIC_HEADER(PARAMS) \ - CMC_CMC_HEAP_CORE_STRUCT(PARAMS) \ - CMC_CMC_HEAP_CORE_HEADER(PARAMS) - -#define CMC_CMC_HEAP_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_HEAP_CORE_SOURCE(PARAMS) - -#define CMC_CMC_HEAP_CORE_PRIVATE_HEADER(PARAMS) \ - struct CMC_PARAM_SNAME(PARAMS); \ - CMC_CMC_HEAP_CORE_HEADER(PARAMS) - -#define CMC_CMC_HEAP_CORE_PRIVATE_SOURCE(PARAMS) \ - CMC_CMC_HEAP_CORE_STRUCT(PARAMS) \ - CMC_CMC_HEAP_CORE_SOURCE(PARAMS) - -/* Lowest level API */ -#define CMC_CMC_HEAP_CORE_STRUCT(PARAMS) \ - CMC_CMC_HEAP_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_CMC_HEAP_CORE_HEADER(PARAMS) \ - CMC_CMC_HEAP_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_CMC_HEAP_CORE_SOURCE(PARAMS) \ - CMC_CMC_HEAP_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -/* ------------------------------------------------------------------------- - * Struct - * ------------------------------------------------------------------------- */ -#define CMC_CMC_HEAP_CORE_STRUCT_(PFX, SNAME, V) \ -\ - /* Heap Structure */ \ - struct SNAME \ - { \ - /* Dynamic array of elements */ \ - V *buffer; \ -\ - /* Current array capacity */ \ - size_t capacity; \ -\ - /* Current amount of elements in the heap */ \ - size_t count; \ -\ - /* Heap order (MaxHeap or MinHeap) */ \ - enum cmc_heap_order HO; \ -\ - /* Flags indicating errors or success */ \ - int flag; \ -\ - /* Value function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ -\ - /* Custom allocation functions */ \ - struct CMC_ALLOC_NODE_NAME *alloc; \ -\ - /* Custom callback functions */ \ - CMC_CALLBACKS_DECL; \ - }; - -/* ------------------------------------------------------------------------- - * Header - * ------------------------------------------------------------------------- */ -#define CMC_CMC_HEAP_CORE_HEADER_(PFX, SNAME, V) \ -\ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(V); \ -\ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(V); \ -\ - /* To string function */ \ - CMC_DEF_FTAB_STR(V); \ -\ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(V); \ -\ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(V); \ -\ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(V); \ - }; \ -\ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, enum cmc_heap_order HO, struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, enum cmc_heap_order HO, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks); \ - void CMC_(PFX, _clear)(struct SNAME * _heap_); \ - void CMC_(PFX, _free)(struct SNAME * _heap_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _heap_, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _insert)(struct SNAME * _heap_, V value); \ - bool CMC_(PFX, _remove)(struct SNAME * _heap_); \ - /* Element Access */ \ - V CMC_(PFX, _peek)(struct SNAME * _heap_); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _heap_, V value); \ - bool CMC_(PFX, _empty)(struct SNAME * _heap_); \ - bool CMC_(PFX, _full)(struct SNAME * _heap_); \ - size_t CMC_(PFX, _count)(struct SNAME * _heap_); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _heap_); \ - int CMC_(PFX, _flag)(struct SNAME * _heap_); \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _heap_, size_t capacity); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _heap_); \ - bool CMC_(PFX, _equals)(struct SNAME * _heap1_, struct SNAME * _heap2_); - -/* ------------------------------------------------------------------------- - * Source - * ------------------------------------------------------------------------- */ -#define CMC_CMC_HEAP_CORE_SOURCE_(PFX, SNAME, V) \ -\ - /* Implementation Detail Functions */ \ - static void CMC_(PFX, _impl_float_up)(struct SNAME * _heap_, size_t index); \ - static void CMC_(PFX, _impl_float_down)(struct SNAME * _heap_, size_t index); \ -\ - struct SNAME *CMC_(PFX, _new)(size_t capacity, enum cmc_heap_order HO, struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - return CMC_(PFX, _new_custom)(capacity, HO, f_val, NULL, NULL); \ - } \ -\ - struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, enum cmc_heap_order HO, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - if (capacity < 1) \ - return NULL; \ -\ - if (HO != CMC_MIN_HEAP && HO != CMC_MAX_HEAP) \ - return NULL; \ -\ - if (!f_val) \ - return NULL; \ -\ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ -\ - struct SNAME *_heap_ = alloc->malloc(sizeof(struct SNAME)); \ -\ - if (!_heap_) \ - return NULL; \ -\ - _heap_->buffer = alloc->calloc(capacity, sizeof(V)); \ -\ - if (!_heap_->buffer) \ - { \ - alloc->free(_heap_); \ - return NULL; \ - } \ -\ - _heap_->capacity = capacity; \ - _heap_->count = 0; \ - _heap_->HO = HO; \ - _heap_->flag = CMC_FLAG_OK; \ - _heap_->f_val = f_val; \ - _heap_->alloc = alloc; \ - CMC_CALLBACKS_ASSIGN(_heap_, callbacks); \ -\ - return _heap_; \ - } \ -\ - void CMC_(PFX, _clear)(struct SNAME * _heap_) \ - { \ - if (_heap_->f_val->free) \ - { \ - for (size_t i = 0; i < _heap_->count; i++) \ - { \ - _heap_->f_val->free(_heap_->buffer[i]); \ - } \ - } \ -\ - memset(_heap_->buffer, 0, sizeof(V) * _heap_->capacity); \ -\ - _heap_->count = 0; \ - _heap_->flag = CMC_FLAG_OK; \ - } \ -\ - void CMC_(PFX, _free)(struct SNAME * _heap_) \ - { \ - if (_heap_->f_val->free) \ - { \ - for (size_t i = 0; i < _heap_->count; i++) \ - { \ - _heap_->f_val->free(_heap_->buffer[i]); \ - } \ - } \ -\ - _heap_->alloc->free(_heap_->buffer); \ - _heap_->alloc->free(_heap_); \ - } \ -\ - void CMC_(PFX, _customize)(struct SNAME * _heap_, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - if (!alloc) \ - _heap_->alloc = &cmc_alloc_node_default; \ - else \ - _heap_->alloc = alloc; \ -\ - CMC_CALLBACKS_ASSIGN(_heap_, callbacks); \ -\ - _heap_->flag = CMC_FLAG_OK; \ - } \ -\ - bool CMC_(PFX, _insert)(struct SNAME * _heap_, V value) \ - { \ - if (CMC_(PFX, _full)(_heap_)) \ - { \ - if (!CMC_(PFX, _resize)(_heap_, _heap_->count * 2)) \ - return false; \ - } \ -\ - _heap_->buffer[_heap_->count++] = value; \ -\ - if (_heap_->count > 1) \ - { \ - CMC_(PFX, _impl_float_up)(_heap_, _heap_->count - 1); \ - } \ -\ - _heap_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_heap_, create); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _remove)(struct SNAME * _heap_) \ - { \ - if (CMC_(PFX, _empty)(_heap_)) \ - { \ - _heap_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - _heap_->buffer[0] = _heap_->buffer[_heap_->count - 1]; \ - _heap_->buffer[_heap_->count - 1] = (V){ 0 }; \ -\ - _heap_->count--; \ -\ - CMC_(PFX, _impl_float_down)(_heap_, 0); \ -\ - _heap_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_heap_, delete); \ -\ - return true; \ - } \ -\ - V CMC_(PFX, _peek)(struct SNAME * _heap_) \ - { \ - if (CMC_(PFX, _empty)(_heap_)) \ - { \ - _heap_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ -\ - _heap_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_heap_, read); \ -\ - return _heap_->buffer[0]; \ - } \ -\ - bool CMC_(PFX, _contains)(struct SNAME * _heap_, V value) \ - { \ - _heap_->flag = CMC_FLAG_OK; \ -\ - bool result = false; \ -\ - for (size_t i = 0; i < _heap_->count; i++) \ - { \ - if (_heap_->f_val->cmp(_heap_->buffer[i], value) == 0) \ - { \ - result = true; \ - break; \ - } \ - } \ -\ - CMC_CALLBACKS_CALL(_heap_, read); \ -\ - return result; \ - } \ -\ - bool CMC_(PFX, _empty)(struct SNAME * _heap_) \ - { \ - return _heap_->count == 0; \ - } \ -\ - bool CMC_(PFX, _full)(struct SNAME * _heap_) \ - { \ - return _heap_->count >= _heap_->capacity; \ - } \ -\ - size_t CMC_(PFX, _count)(struct SNAME * _heap_) \ - { \ - return _heap_->count; \ - } \ -\ - size_t CMC_(PFX, _capacity)(struct SNAME * _heap_) \ - { \ - return _heap_->capacity; \ - } \ -\ - int CMC_(PFX, _flag)(struct SNAME * _heap_) \ - { \ - return _heap_->flag; \ - } \ -\ - bool CMC_(PFX, _resize)(struct SNAME * _heap_, size_t capacity) \ - { \ - _heap_->flag = CMC_FLAG_OK; \ -\ - if (_heap_->capacity == capacity) \ - goto success; \ -\ - if (capacity < _heap_->count) \ - { \ - _heap_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ -\ - V *new_buffer = _heap_->alloc->realloc(_heap_->buffer, sizeof(V) * capacity); \ -\ - if (!new_buffer) \ - { \ - _heap_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ -\ - /* TODO zero out new slots */ \ -\ - _heap_->buffer = new_buffer; \ - _heap_->capacity = capacity; \ -\ - success: \ -\ - CMC_CALLBACKS_CALL(_heap_, resize); \ -\ - return true; \ - } \ -\ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _heap_) \ - { \ - struct SNAME *result = \ - CMC_(PFX, _new_custom)(_heap_->capacity, _heap_->HO, _heap_->f_val, _heap_->alloc, NULL); \ -\ - if (!result) \ - { \ - _heap_->flag = CMC_FLAG_ERROR; \ - return NULL; \ - } \ -\ - CMC_CALLBACKS_ASSIGN(result, _heap_->callbacks); \ -\ - if (_heap_->f_val->cpy) \ - { \ - for (size_t i = 0; i < _heap_->count; i++) \ - result->buffer[i] = _heap_->f_val->cpy(_heap_->buffer[i]); \ - } \ - else \ - memcpy(result->buffer, _heap_->buffer, sizeof(V) * _heap_->count); \ -\ - result->count = _heap_->count; \ -\ - _heap_->flag = CMC_FLAG_OK; \ -\ - return result; \ - } \ -\ - bool CMC_(PFX, _equals)(struct SNAME * _heap1_, struct SNAME * _heap2_) \ - { \ - _heap1_->flag = CMC_FLAG_OK; \ - _heap2_->flag = CMC_FLAG_OK; \ -\ - if (_heap1_->count != _heap2_->count) \ - return false; \ -\ - for (size_t i = 0; i < _heap1_->count; i++) \ - { \ - if (_heap1_->f_val->cmp(_heap1_->buffer[i], _heap2_->buffer[i]) != 0) \ - return false; \ - } \ -\ - return true; \ - } \ -\ - static void CMC_(PFX, _impl_float_up)(struct SNAME * _heap_, size_t index) \ - { \ - /* Current index */ \ - size_t C = index; \ - V child = _heap_->buffer[C]; \ - V parent = _heap_->buffer[(index - 1) / 2]; \ -\ - int mod = _heap_->HO; \ -\ - while (C > 0 && _heap_->f_val->cmp(child, parent) * mod > 0) \ - { \ - /* Swap between C (current element) and its parent */ \ - V tmp = _heap_->buffer[C]; \ - _heap_->buffer[C] = _heap_->buffer[(C - 1) / 2]; \ - _heap_->buffer[(C - 1) / 2] = tmp; \ -\ - /* Go to parent */ \ - C = (C - 1) / 2; \ -\ - /* Prevent the two lines below from accessing a negative index */ \ - if (C == 0) \ - break; \ -\ - child = _heap_->buffer[C]; \ - parent = _heap_->buffer[(C - 1) / 2]; \ - } \ - } \ -\ - static void CMC_(PFX, _impl_float_down)(struct SNAME * _heap_, size_t index) \ - { \ - int mod = _heap_->HO; \ -\ - while (index < _heap_->count) \ - { \ - size_t L = 2 * index + 1; \ - size_t R = 2 * index + 2; \ - size_t C = index; \ -\ - /* Determine if we swap with the left or right element */ \ - if (L < _heap_->count && _heap_->f_val->cmp(_heap_->buffer[L], _heap_->buffer[C]) * mod > 0) \ - { \ - C = L; \ - } \ -\ - if (R < _heap_->count && _heap_->f_val->cmp(_heap_->buffer[R], _heap_->buffer[C]) * mod > 0) \ - { \ - C = R; \ - } \ -\ - /* Swap only if either left or right was picked, otherwise done */ \ - if (C != index) \ - { \ - V tmp = _heap_->buffer[index]; \ - _heap_->buffer[index] = _heap_->buffer[C]; \ - _heap_->buffer[C] = tmp; \ -\ - index = C; \ - } \ - else \ - break; \ - } \ - } - -#endif /* CMC_CMC_HEAP_H */ diff --git a/src/cmc_intervalheap.h b/src/cmc_intervalheap.h deleted file mode 100644 index 2be1102..0000000 --- a/src/cmc_intervalheap.h +++ /dev/null @@ -1,924 +0,0 @@ -/** - * Copyright (c) 2019 Leonardo Vencovsky - * - * This file is part of the C Macro Collections Libray. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * cmc_intervalheap.h - * - * Creation Date: 06/07/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -/** - * An interval heap is a specialized heap with: - * - * - O(1) - Find Min - * - O(1) - Find Max - * - O(log n) - Insert - * - O(log n) - Remove Min - * - O(log n) - Remove Max - */ - -#ifndef CMC_CMC_INTERVALHEAP_H -#define CMC_CMC_INTERVALHEAP_H - -/* ------------------------------------------------------------------------- - * Core functionalities of the C Macro Collections Library - * ------------------------------------------------------------------------- */ -#include "cor_core.h" - -/** - * Core IntervalHeap implementation - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_CMC_INTERVALHEAP_CORE(ACCESS, FILE, PARAMS) \ - CMC_(CMC_(CMC_CMC_INTERVALHEAP_CORE_, ACCESS), CMC_(_, FILE))(PARAMS) - -/* PRIVATE or PUBLIC solver */ -#define CMC_CMC_INTERVALHEAP_CORE_PUBLIC_HEADER(PARAMS) \ - CMC_CMC_INTERVALHEAP_CORE_STRUCT(PARAMS) \ - CMC_CMC_INTERVALHEAP_CORE_HEADER(PARAMS) - -#define CMC_CMC_INTERVALHEAP_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_INTERVALHEAP_CORE_SOURCE(PARAMS) - -#define CMC_CMC_INTERVALHEAP_CORE_PRIVATE_HEADER(PARAMS) \ - struct CMC_PARAM_SNAME(PARAMS); \ - CMC_CMC_INTERVALHEAP_CORE_HEADER(PARAMS) - -#define CMC_CMC_INTERVALHEAP_CORE_PRIVATE_SOURCE(PARAMS) \ - CMC_CMC_INTERVALHEAP_CORE_STRUCT(PARAMS) \ - CMC_CMC_INTERVALHEAP_CORE_SOURCE(PARAMS) - -/* Lowest level API */ -#define CMC_CMC_INTERVALHEAP_CORE_STRUCT(PARAMS) \ - CMC_CMC_INTERVALHEAP_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_CMC_INTERVALHEAP_CORE_HEADER(PARAMS) \ - CMC_CMC_INTERVALHEAP_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_CMC_INTERVALHEAP_CORE_SOURCE(PARAMS) \ - CMC_CMC_INTERVALHEAP_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -/* ------------------------------------------------------------------------- - * Struct - * ------------------------------------------------------------------------- */ -#define CMC_CMC_INTERVALHEAP_CORE_STRUCT_(PFX, SNAME, V) \ -\ - /* IntervalHeap Structure */ \ - struct SNAME \ - { \ - /* Dynamic array of elements */ \ - /* buffer[n][0] is MinHeap and buffer[n][1] is MaxHeap */ \ - V (*buffer)[2]; \ -\ - /* Current array capacity */ \ - size_t capacity; \ -\ - /* Current amount of pairs of values in the array */ \ - size_t size; \ -\ - /* Current amount of elements in the heap */ \ - size_t count; \ -\ - /* Flags indicating errors or success */ \ - int flag; \ -\ - /* Value function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ -\ - /* Custom allocation functions */ \ - struct CMC_ALLOC_NODE_NAME *alloc; \ -\ - /* Custom callback functions */ \ - CMC_CALLBACKS_DECL; \ - }; - -/* ------------------------------------------------------------------------- - * Header - * ------------------------------------------------------------------------- */ -#define CMC_CMC_INTERVALHEAP_CORE_HEADER_(PFX, SNAME, V) \ -\ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(V); \ -\ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(V); \ -\ - /* To string function */ \ - CMC_DEF_FTAB_STR(V); \ -\ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(V); \ -\ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(V); \ -\ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(V); \ - }; \ -\ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks); \ - void CMC_(PFX, _clear)(struct SNAME * _heap_); \ - void CMC_(PFX, _free)(struct SNAME * _heap_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _heap_, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _insert)(struct SNAME * _heap_, V value); \ - bool CMC_(PFX, _remove_max)(struct SNAME * _heap_); \ - bool CMC_(PFX, _remove_min)(struct SNAME * _heap_); \ - /* Collection Update */ \ - bool CMC_(PFX, _update_max)(struct SNAME * _heap_, V value); \ - bool CMC_(PFX, _update_min)(struct SNAME * _heap_, V value); \ - /* Element Access */ \ - V CMC_(PFX, _max)(struct SNAME * _heap_); \ - V CMC_(PFX, _min)(struct SNAME * _heap_); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _heap_, V value); \ - bool CMC_(PFX, _empty)(struct SNAME * _heap_); \ - bool CMC_(PFX, _full)(struct SNAME * _heap_); \ - size_t CMC_(PFX, _count)(struct SNAME * _heap_); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _heap_); \ - int CMC_(PFX, _flag)(struct SNAME * _heap_); \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _heap_, size_t capacity); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _heap_); \ - bool CMC_(PFX, _equals)(struct SNAME * _heap1_, struct SNAME * _heap2_); - -/* ------------------------------------------------------------------------- - * Source - * ------------------------------------------------------------------------- */ -#define CMC_CMC_INTERVALHEAP_CORE_SOURCE_(PFX, SNAME, V) \ -\ - /* Implementation Detail Functions */ \ - static void CMC_(PFX, _impl_float_up_max)(struct SNAME * _heap_); \ - static void CMC_(PFX, _impl_float_up_min)(struct SNAME * _heap_); \ - static void CMC_(PFX, _impl_float_down_max)(struct SNAME * _heap_); \ - static void CMC_(PFX, _impl_float_down_min)(struct SNAME * _heap_); \ -\ - struct SNAME *CMC_(PFX, _new)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - return CMC_(PFX, _new_custom)(capacity, f_val, NULL, NULL); \ - } \ -\ - struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - if (capacity == 0 || capacity == UINTMAX_MAX) \ - return NULL; \ -\ - if (!f_val) \ - return NULL; \ -\ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ -\ - struct SNAME *_heap_ = alloc->malloc(sizeof(struct SNAME)); \ -\ - if (!_heap_) \ - return NULL; \ -\ - capacity = (capacity + capacity % 2) / 2; \ -\ - _heap_->buffer = alloc->calloc(capacity, sizeof(V[2])); \ -\ - if (!_heap_->buffer) \ - { \ - alloc->free(_heap_); \ - return NULL; \ - } \ -\ - _heap_->capacity = capacity; \ - _heap_->size = 0; \ - _heap_->count = 0; \ - _heap_->flag = CMC_FLAG_OK; \ - _heap_->f_val = f_val; \ - _heap_->alloc = alloc; \ - CMC_CALLBACKS_ASSIGN(_heap_, callbacks); \ -\ - return _heap_; \ - } \ -\ - void CMC_(PFX, _clear)(struct SNAME * _heap_) \ - { \ - if (_heap_->f_val->free) \ - { \ - for (size_t i = 0; i < _heap_->count; i++) \ - { \ - _heap_->f_val->free(_heap_->buffer[i / 2][i % 2]); \ - } \ - } \ -\ - memset(_heap_->buffer, 0, sizeof(V[2]) * _heap_->capacity); \ -\ - _heap_->size = 0; \ - _heap_->count = 0; \ - _heap_->flag = CMC_FLAG_OK; \ - } \ -\ - void CMC_(PFX, _free)(struct SNAME * _heap_) \ - { \ - if (_heap_->f_val->free) \ - { \ - for (size_t i = 0; i < _heap_->count; i++) \ - { \ - _heap_->f_val->free(_heap_->buffer[i / 2][i % 2]); \ - } \ - } \ -\ - _heap_->alloc->free(_heap_->buffer); \ -\ - _heap_->alloc->free(_heap_); \ - } \ -\ - void CMC_(PFX, _customize)(struct SNAME * _heap_, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - if (!alloc) \ - _heap_->alloc = &cmc_alloc_node_default; \ - else \ - _heap_->alloc = alloc; \ -\ - CMC_CALLBACKS_ASSIGN(_heap_, callbacks); \ -\ - _heap_->flag = CMC_FLAG_OK; \ - } \ -\ - bool CMC_(PFX, _insert)(struct SNAME * _heap_, V value) \ - { \ - if (CMC_(PFX, _full)(_heap_)) \ - { \ - if (!CMC_(PFX, _resize)(_heap_, _heap_->capacity * 4)) \ - return false; \ - } \ -\ - if (_heap_->count % 2 == 0) \ - { \ - /* Occupying a new node */ \ - _heap_->buffer[_heap_->size][0] = value; \ - _heap_->buffer[_heap_->size][1] = (V){ 0 }; \ -\ - _heap_->size++; \ - } \ - else \ - { \ - V(*node)[2] = &(_heap_->buffer[_heap_->size - 1]); \ -\ - /* Decide if the new element goes into the MinHeap or MaxHeap */ \ - if (_heap_->f_val->cmp((*node)[0], value) > 0) \ - { \ - /* Swap current value and add new element to the MinHeap */ \ - (*node)[1] = (*node)[0]; \ - (*node)[0] = value; \ - } \ - else \ - { \ - /* No need to swap and add the new element to the MaxHeap */ \ - (*node)[1] = value; \ - } \ - } \ -\ - _heap_->count++; \ - _heap_->flag = CMC_FLAG_OK; \ -\ - if (_heap_->count > 2) \ - { \ - /* Determine wheather to do a MaxHeap insert or a MinHeap */ \ - /* insert. For any integer this index calculation results in */ \ - /* an even number representing the parent of the last value */ \ - V(*parent)[2] = &(_heap_->buffer[(_heap_->size - 2) / 2]); \ -\ - if (_heap_->f_val->cmp((*parent)[0], value) > 0) \ - CMC_(PFX, _impl_float_up_min)(_heap_); \ - else if (_heap_->f_val->cmp((*parent)[1], value) < 0) \ - CMC_(PFX, _impl_float_up_max)(_heap_); \ - /* else no float up required */ \ - } \ -\ - CMC_CALLBACKS_CALL(_heap_, create); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _remove_max)(struct SNAME * _heap_) \ - { \ - if (CMC_(PFX, _empty)(_heap_)) \ - { \ - _heap_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - if (_heap_->count == 1) \ - { \ - _heap_->buffer[0][0] = (V){ 0 }; \ -\ - _heap_->count--; \ - _heap_->size--; \ -\ - goto success; \ - } \ -\ - /* Swap the result with the last element in the MaxHeap and float */ \ - /* it down */ \ - V(*last_node)[2] = &(_heap_->buffer[_heap_->size - 1]); \ -\ - if (_heap_->count % 2 == 1) \ - { \ - /* Grab from MinHeap and discard last node */ \ - _heap_->buffer[0][1] = (*last_node)[0]; \ -\ - (*last_node)[0] = (V){ 0 }; \ -\ - _heap_->size--; \ - } \ - else \ - { \ - _heap_->buffer[0][1] = (*last_node)[1]; \ -\ - (*last_node)[1] = (V){ 0 }; \ - } \ -\ - _heap_->count--; \ -\ - /* FLoat Down on the MaxHeap */ \ - CMC_(PFX, _impl_float_down_max)(_heap_); \ -\ - success: \ -\ - _heap_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_heap_, delete); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _remove_min)(struct SNAME * _heap_) \ - { \ - if (CMC_(PFX, _empty)(_heap_)) \ - { \ - _heap_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - if (_heap_->count == 1) \ - { \ - _heap_->buffer[0][0] = (V){ 0 }; \ -\ - _heap_->count--; \ - _heap_->size--; \ -\ - goto success; \ - } \ -\ - /* Swap the result with the last element in the MinHeap and float */ \ - /* it down */ \ - V(*last_node)[2] = &(_heap_->buffer[_heap_->size - 1]); \ -\ - _heap_->buffer[0][0] = (*last_node)[0]; \ -\ - if (_heap_->count % 2 == 1) \ - { \ - /* Discard last node */ \ - (*last_node)[0] = (V){ 0 }; \ -\ - _heap_->size--; \ - } \ - else \ - { \ - /* Place the MaxHeap value in the MinHeap value spot */ \ - (*last_node)[0] = (*last_node)[1]; \ - (*last_node)[1] = (V){ 0 }; \ - } \ -\ - _heap_->count--; \ -\ - /* FLoat Down on the MinHeap */ \ - CMC_(PFX, _impl_float_down_min)(_heap_); \ -\ - success: \ -\ - _heap_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_heap_, delete); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _update_max)(struct SNAME * _heap_, V value) \ - { \ - if (CMC_(PFX, _empty)(_heap_)) \ - { \ - _heap_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - if (_heap_->count == 1) \ - { \ - _heap_->buffer[0][0] = value; \ - } \ - else if (_heap_->f_val->cmp(value, _heap_->buffer[0][0]) < 0) \ - { \ - /* Corner case: we are updating the Max value but it is less */ \ - /* than the Min value */ \ - _heap_->buffer[0][1] = _heap_->buffer[0][0]; \ - _heap_->buffer[0][0] = value; \ -\ - CMC_(PFX, _impl_float_down_max)(_heap_); \ - } \ - else \ - { \ - /* Update Max element and float it down */ \ - _heap_->buffer[0][1] = value; \ -\ - CMC_(PFX, _impl_float_down_max)(_heap_); \ - } \ -\ - _heap_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_heap_, update); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _update_min)(struct SNAME * _heap_, V value) \ - { \ - if (CMC_(PFX, _empty)(_heap_)) \ - { \ - _heap_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - if (_heap_->count == 1) \ - { \ - _heap_->buffer[0][0] = value; \ - } \ - else if (_heap_->f_val->cmp(value, _heap_->buffer[0][1]) > 0) \ - { \ - /* Corner case: we are updating the Min value but it is greater */ \ - /* than the Max value. */ \ - _heap_->buffer[0][0] = _heap_->buffer[0][1]; \ - _heap_->buffer[0][1] = value; \ -\ - CMC_(PFX, _impl_float_down_min)(_heap_); \ - } \ - else \ - { \ - /* Update Min element and float it down */ \ - _heap_->buffer[0][0] = value; \ -\ - CMC_(PFX, _impl_float_down_min)(_heap_); \ - } \ -\ - _heap_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_heap_, update); \ -\ - return true; \ - } \ -\ - V CMC_(PFX, _max)(struct SNAME * _heap_) \ - { \ - if (CMC_(PFX, _empty)(_heap_)) \ - { \ - _heap_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ -\ - _heap_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_heap_, read); \ -\ - /* If there is only one element, then the maximum element is the */ \ - /* same as the one in the MinHeap */ \ - if (_heap_->count == 1) \ - return _heap_->buffer[0][0]; \ -\ - return _heap_->buffer[0][1]; \ - } \ -\ - V CMC_(PFX, _min)(struct SNAME * _heap_) \ - { \ - if (CMC_(PFX, _empty)(_heap_)) \ - { \ - _heap_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ -\ - _heap_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_heap_, read); \ -\ - return _heap_->buffer[0][0]; \ - } \ -\ - bool CMC_(PFX, _contains)(struct SNAME * _heap_, V value) \ - { \ - _heap_->flag = CMC_FLAG_OK; \ -\ - bool result = false; \ -\ - for (size_t i = 0; i < _heap_->count; i++) \ - { \ - if (_heap_->f_val->cmp(_heap_->buffer[i / 2][i % 2], value) == 0) \ - { \ - result = true; \ - break; \ - } \ - } \ -\ - CMC_CALLBACKS_CALL(_heap_, read); \ -\ - return result; \ - } \ -\ - bool CMC_(PFX, _empty)(struct SNAME * _heap_) \ - { \ - return _heap_->count == 0; \ - } \ -\ - bool CMC_(PFX, _full)(struct SNAME * _heap_) \ - { \ - /* The heap is full if all nodes are completely filled */ \ - return _heap_->size >= _heap_->capacity && _heap_->count % 2 == 0; \ - } \ -\ - size_t CMC_(PFX, _count)(struct SNAME * _heap_) \ - { \ - return _heap_->count; \ - } \ -\ - size_t CMC_(PFX, _capacity)(struct SNAME * _heap_) \ - { \ - return _heap_->capacity; \ - } \ -\ - int CMC_(PFX, _flag)(struct SNAME * _heap_) \ - { \ - return _heap_->flag; \ - } \ -\ - bool CMC_(PFX, _resize)(struct SNAME * _heap_, size_t capacity) \ - { \ - if (_heap_->capacity == capacity) \ - goto success; \ -\ - if (capacity < _heap_->count) \ - { \ - _heap_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ -\ - /* Prevent overflow */ \ - if (capacity == UINTMAX_MAX) \ - { \ - _heap_->flag = CMC_FLAG_ERROR; \ - return false; \ - } \ -\ - capacity += capacity % 2; \ -\ - V(*new_buffer)[2] = _heap_->alloc->realloc(_heap_->buffer, sizeof(V[2]) * capacity); \ -\ - if (!new_buffer) \ - { \ - _heap_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ -\ - if (capacity > _heap_->capacity) \ - { \ - memset(new_buffer + _heap_->capacity, 0, sizeof(V[2]) * (capacity - _heap_->capacity)); \ - } \ -\ - _heap_->buffer = new_buffer; \ - _heap_->capacity = capacity; \ -\ - success: \ -\ - _heap_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_heap_, resize); \ -\ - return true; \ - } \ -\ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _heap_) \ - { \ - struct SNAME *result = _heap_->alloc->malloc(sizeof(struct SNAME)); \ -\ - if (!result) \ - { \ - _heap_->flag = CMC_FLAG_ALLOC; \ - return NULL; \ - } \ -\ - memcpy(result, _heap_, sizeof(struct SNAME)); \ -\ - result->buffer = _heap_->alloc->malloc(sizeof(V[2]) * _heap_->capacity); \ -\ - if (!result->buffer) \ - { \ - _heap_->alloc->free(result); \ - _heap_->flag = CMC_FLAG_ALLOC; \ - return NULL; \ - } \ -\ - if (_heap_->f_val->cpy) \ - { \ - for (size_t i = 0; i < _heap_->count; i++) \ - result->buffer[i / 2][i % 2] = _heap_->f_val->cpy(_heap_->buffer[i / 2][i % 2]); \ - } \ - else \ - memcpy(result->buffer, _heap_->buffer, sizeof(V[2]) * _heap_->capacity); \ -\ - result->capacity = _heap_->capacity; \ - result->size = _heap_->size; \ - result->count = _heap_->count; \ - result->flag = CMC_FLAG_OK; \ - result->f_val = _heap_->f_val; \ - result->alloc = _heap_->alloc; \ - CMC_CALLBACKS_ASSIGN(result, _heap_->callbacks); \ -\ - _heap_->flag = CMC_FLAG_OK; \ -\ - return result; \ - } \ -\ - bool CMC_(PFX, _equals)(struct SNAME * _heap1_, struct SNAME * _heap2_) \ - { \ - _heap1_->flag = CMC_FLAG_OK; \ - _heap2_->flag = CMC_FLAG_OK; \ -\ - if (_heap1_->count != _heap2_->count) \ - return false; \ -\ - for (size_t i = 0; i < _heap1_->count; i++) \ - { \ - V value1 = _heap1_->buffer[i / 2][i % 2]; \ - V value2 = _heap2_->buffer[i / 2][i % 2]; \ -\ - if (_heap1_->f_val->cmp(value1, value2) != 0) \ - return false; \ - } \ -\ - return true; \ - } \ -\ - static void CMC_(PFX, _impl_float_up_max)(struct SNAME * _heap_) \ - { \ - size_t index = _heap_->size - 1; \ -\ - V(*curr_node)[2] = &(_heap_->buffer[index]); \ -\ - /* FLoat Up on the MaxHeap */ \ - while (index > 0) \ - { \ - /* Parent index */ \ - size_t P_index = (index - 1) / 2; \ -\ - V(*parent)[2] = &(_heap_->buffer[P_index]); \ -\ - if (index == _heap_->size - 1 && _heap_->count % 2 != 0) \ - { \ - /* In this case, the current node has no MaxHeap value so */ \ - /* we instead compare with the MinHeap value */ \ - if (_heap_->f_val->cmp((*curr_node)[0], (*parent)[1]) < 0) \ - break; \ -\ - /* Since the comparison above passed now we need to swap */ \ - /* the current node with the parent but it will have to be */ \ - /* done with the node's MinHeap value since the MaxHeap */ \ - /* value doesn't exist */ \ - V tmp = (*curr_node)[0]; \ - (*curr_node)[0] = (*parent)[1]; \ - (*parent)[1] = tmp; \ - } \ - else \ - { \ - /* Usual case, just compare both MaxHeap values */ \ - if (_heap_->f_val->cmp((*curr_node)[1], (*parent)[1]) < 0) \ - break; \ -\ - /* Swap with parent and repeat */ \ - V tmp = (*curr_node)[1]; \ - (*curr_node)[1] = (*parent)[1]; \ - (*parent)[1] = tmp; \ - } \ -\ - /* Update indexe and node */ \ - index = P_index; \ - curr_node = parent; \ - } \ - } \ -\ - static void CMC_(PFX, _impl_float_up_min)(struct SNAME * _heap_) \ - { \ - size_t index = _heap_->size - 1; \ -\ - V(*curr_node)[2] = &(_heap_->buffer[index]); \ -\ - /* FLoat Up on the MinHeap */ \ - while (index > 0) \ - { \ - /* Parent index */ \ - size_t P_index = (index - 1) / 2; \ -\ - V(*parent)[2] = &(_heap_->buffer[P_index]); \ -\ - if (_heap_->f_val->cmp((*curr_node)[0], (*parent)[0]) >= 0) \ - break; \ -\ - /* Swap with parent and repeat */ \ - V tmp = (*curr_node)[0]; \ - (*curr_node)[0] = (*parent)[0]; \ - (*parent)[0] = tmp; \ -\ - /* Update indexe and node */ \ - index = P_index; \ - curr_node = parent; \ - } \ - } \ -\ - static void CMC_(PFX, _impl_float_down_max)(struct SNAME * _heap_) \ - { \ - /* Floats Down from the MinHeap */ \ - size_t index = 0; \ -\ - V(*curr_node)[2] = &(_heap_->buffer[index]); \ -\ - while (true) \ - { \ - /* If there are no children it is done */ \ - if (2 * index + 1 >= _heap_->size) \ - break; \ -\ - /* Child index to be compared with current value */ \ - size_t child; \ - size_t L_index = index * 2 + 1; \ - size_t R_index = index * 2 + 2; \ -\ - /* If there are two children, pick the smallest one */ \ - if (R_index < _heap_->size) \ - { \ - V(*L)[2] = &(_heap_->buffer[L_index]); \ - V(*R)[2] = &(_heap_->buffer[R_index]); \ -\ - /* If the right child is the last node and there is no */ \ - /* MaxHeap value */ \ - /* then do the comparison with the MinHeap value */ \ - if (R_index == _heap_->size - 1 && _heap_->count % 2 != 0) \ - child = _heap_->f_val->cmp((*L)[1], (*R)[0]) > 0 ? L_index : R_index; \ - else \ - child = _heap_->f_val->cmp((*L)[1], (*R)[1]) > 0 ? L_index : R_index; \ - } \ - /* Pick the only one available */ \ - else \ - child = L_index; \ -\ - V(*child_node)[2] = &(_heap_->buffer[child]); \ -\ - /* Again, check if the child node is the last one and has no */ \ - /* MaxHeap value */ \ - if (child == _heap_->size - 1 && _heap_->count % 2 != 0) \ - { \ - /* Odd case, compare with MinHeap value */ \ - /* If current value is not less than the child node's */ \ - /* value it is done */ \ - if (_heap_->f_val->cmp((*curr_node)[1], (*child_node)[0]) >= 0) \ - break; \ -\ - /* Otherwise swap and continue */ \ - V tmp = (*child_node)[0]; \ - (*child_node)[0] = (*curr_node)[1]; \ - (*curr_node)[1] = tmp; \ - } \ - else \ - { \ - /* If current value is not less than the child node's */ \ - /* value it is done */ \ - if (_heap_->f_val->cmp((*curr_node)[1], (*child_node)[1]) >= 0) \ - break; \ -\ - /* Otherwise swap and continue */ \ - V tmp = (*child_node)[1]; \ - (*child_node)[1] = (*curr_node)[1]; \ - (*curr_node)[1] = tmp; \ -\ - /* Check if the MinHeap and MaxHeap values need to be */ \ - /* swapped */ \ - if (_heap_->f_val->cmp((*child_node)[0], (*child_node)[1]) > 0) \ - { \ - /* Swap because the MinHeap value is greater than the */ \ - /* MaxHeap value */ \ - tmp = (*child_node)[0]; \ - (*child_node)[0] = (*child_node)[1]; \ - (*child_node)[1] = tmp; \ - } \ - } \ -\ - /* Update index and node */ \ - index = child; \ - curr_node = child_node; \ - } \ - } \ -\ - static void CMC_(PFX, _impl_float_down_min)(struct SNAME * _heap_) \ - { \ - /* Floats Down from the MinHeap */ \ - size_t index = 0; \ -\ - V(*curr_node)[2] = &(_heap_->buffer[index]); \ -\ - while (true) \ - { \ - /* If there are no children it is done */ \ - if (2 * index + 1 >= _heap_->size) \ - break; \ -\ - /* Child index to be compared with current value */ \ - size_t child; \ - size_t L_index = index * 2 + 1; \ - size_t R_index = index * 2 + 2; \ -\ - /* If there are two children, pick the smallest one */ \ - if (R_index < _heap_->size) \ - { \ - V(*L)[2] = &(_heap_->buffer[L_index]); \ - V(*R)[2] = &(_heap_->buffer[R_index]); \ -\ - child = _heap_->f_val->cmp((*L)[0], (*R)[0]) < 0 ? L_index : R_index; \ - } \ - /* Pick the only one available */ \ - else \ - child = L_index; \ -\ - V(*child_node)[2] = &(_heap_->buffer[child]); \ -\ - /* If current value is smaller than the child node's value, it */ \ - /* is done */ \ - if (_heap_->f_val->cmp((*curr_node)[0], (*child_node)[0]) < 0) \ - break; \ -\ - /* Otherwise swap and continue */ \ - V tmp = (*child_node)[0]; \ - (*child_node)[0] = (*curr_node)[0]; \ - (*curr_node)[0] = tmp; \ -\ - /* If the child node is the last node check if the MinHeap and */ \ - /* MaxHeap values need to be swapped */ \ - if (child != _heap_->size - 1 || _heap_->count % 2 == 0) \ - { \ - if (_heap_->f_val->cmp((*child_node)[0], (*child_node)[1]) > 0) \ - { \ - /* Swap because the MinHeap value is greater than the */ \ - /* MaxHeap value */ \ - tmp = (*child_node)[0]; \ - (*child_node)[0] = (*child_node)[1]; \ - (*child_node)[1] = tmp; \ - } \ - } \ -\ - /* Update index and node */ \ - index = child; \ - curr_node = child_node; \ - } \ - } - -#endif /* CMC_CMC_INTERVALHEAP_H */ diff --git a/src/cmc_linkedlist.h b/src/cmc_linkedlist.h deleted file mode 100644 index 692269f..0000000 --- a/src/cmc_linkedlist.h +++ /dev/null @@ -1,650 +0,0 @@ -/** - * Copyright (c) 2019 Leonardo Vencovsky - * - * This file is part of the C Macro Collections Libray. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * cmc_linkedlist.h - * - * Creation Date: 22/03/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -/** - * LinkedList - * - * A LinkedList is a linear collection of elements, whose order is not given by - * their physical placement in memory. Instead, each element points to the next - * (singly-linked list) and to a previous one (doubly-linked list). It consists - * of nodes connected by these next or previous pointers. Unlike an array, the - * LinkedList can indefinitely grow. - * - * Implementation - * - * The LinkedList is implemented as a doubly-linked list and allows insertions - * and removals at both ends in O(1) and in a given index in O(N). The list has - * a head and tail pointer. The head points to the first element in the sequence - * and tail points to the last. - */ - -#ifndef CMC_CMC_LINKEDLIST_H -#define CMC_CMC_LINKEDLIST_H - -/* ------------------------------------------------------------------------- - * Core functionalities of the C Macro Collections Library - * ------------------------------------------------------------------------- */ -#include "cor_core.h" - -/** - * Core LinkedList implementation - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_CMC_LINKEDLIST_CORE(ACCESS, FILE, PARAMS) \ - CMC_(CMC_(CMC_CMC_LINKEDLIST_CORE_, ACCESS), CMC_(_, FILE))(PARAMS) - -/* PRIVATE or PUBLIC solver */ -#define CMC_CMC_LINKEDLIST_CORE_PUBLIC_HEADER(PARAMS) \ - CMC_CMC_LINKEDLIST_CORE_STRUCT(PARAMS) \ - CMC_CMC_LINKEDLIST_CORE_HEADER(PARAMS) - -#define CMC_CMC_LINKEDLIST_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_LINKEDLIST_CORE_SOURCE(PARAMS) - -#define CMC_CMC_LINKEDLIST_CORE_PRIVATE_HEADER(PARAMS) \ - struct CMC_PARAM_SNAME(PARAMS); \ - CMC_CMC_LINKEDLIST_CORE_HEADER(PARAMS) - -#define CMC_CMC_LINKEDLIST_CORE_PRIVATE_SOURCE(PARAMS) \ - CMC_CMC_LINKEDLIST_CORE_STRUCT(PARAMS) \ - CMC_CMC_LINKEDLIST_CORE_SOURCE(PARAMS) - -/* Lowest level API */ -#define CMC_CMC_LINKEDLIST_CORE_STRUCT(PARAMS) \ - CMC_CMC_LINKEDLIST_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_CMC_LINKEDLIST_CORE_HEADER(PARAMS) \ - CMC_CMC_LINKEDLIST_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_CMC_LINKEDLIST_CORE_SOURCE(PARAMS) \ - CMC_CMC_LINKEDLIST_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -/* ------------------------------------------------------------------------- - * Struct - * ------------------------------------------------------------------------- */ -#define CMC_CMC_LINKEDLIST_CORE_STRUCT_(PFX, SNAME, V) \ -\ - /* Linked List Structure */ \ - struct SNAME \ - { \ - /* First node in the list */ \ - struct CMC_DEF_NODE(SNAME) * head; \ -\ - /* Last node in the list */ \ - struct CMC_DEF_NODE(SNAME) * tail; \ -\ - /* Current amount of elements in the list */ \ - size_t count; \ -\ - /* Flags indicating errors or success */ \ - int flag; \ -\ - /* Value function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ -\ - /* Custom allocation functions */ \ - struct CMC_ALLOC_NODE_NAME *alloc; \ -\ - /* Custom callback functions */ \ - CMC_CALLBACKS_DECL; \ - }; \ -\ - /* Doubly-linked list node */ \ - struct CMC_DEF_NODE(SNAME) \ - { \ - /* Node's value */ \ - V value; \ -\ - /* Pointer to the next node on the linked list */ \ - struct CMC_DEF_NODE(SNAME) * next; \ -\ - /* Pointer to the previous node on the linked list */ \ - struct CMC_DEF_NODE(SNAME) * prev; \ - }; - -/* ------------------------------------------------------------------------- - * Header - * ------------------------------------------------------------------------- */ -#define CMC_CMC_LINKEDLIST_CORE_HEADER_(PFX, SNAME, V) \ -\ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(V); \ -\ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(V); \ -\ - /* To string function */ \ - CMC_DEF_FTAB_STR(V); \ -\ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(V); \ -\ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(V); \ -\ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(V); \ - }; \ -\ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks); \ - void CMC_(PFX, _clear)(struct SNAME * _list_); \ - void CMC_(PFX, _free)(struct SNAME * _list_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _list_, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _push_front)(struct SNAME * _list_, V value); \ - bool CMC_(PFX, _push_at)(struct SNAME * _list_, V value, size_t index); \ - bool CMC_(PFX, _push_back)(struct SNAME * _list_, V value); \ - bool CMC_(PFX, _pop_front)(struct SNAME * _list_); \ - bool CMC_(PFX, _pop_at)(struct SNAME * _list_, size_t index); \ - bool CMC_(PFX, _pop_back)(struct SNAME * _list_); \ - /* Element Access */ \ - V CMC_(PFX, _front)(struct SNAME * _list_); \ - V CMC_(PFX, _get)(struct SNAME * _list_, size_t index); \ - V *CMC_(PFX, _get_ref)(struct SNAME * _list_, size_t index); \ - V CMC_(PFX, _back)(struct SNAME * _list_); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _list_, V value); \ - bool CMC_(PFX, _empty)(struct SNAME * _list_); \ - size_t CMC_(PFX, _count)(struct SNAME * _list_); \ - int CMC_(PFX, _flag)(struct SNAME * _list_); \ - /* Collection Utility */ \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_); \ - bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_); - -/* ------------------------------------------------------------------------- - * Source - * ------------------------------------------------------------------------- */ -#define CMC_CMC_LINKEDLIST_CORE_SOURCE_(PFX, SNAME, V) \ -\ - /* Implementation Detail Functions */ \ - /* None */ \ -\ - struct SNAME *CMC_(PFX, _new)(struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - return CMC_(PFX, _new_custom)(f_val, NULL, NULL); \ - } \ -\ - struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - if (!f_val) \ - return NULL; \ -\ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ -\ - struct SNAME *_list_ = alloc->malloc(sizeof(struct SNAME)); \ -\ - if (!_list_) \ - return NULL; \ -\ - _list_->count = 0; \ - _list_->head = NULL; \ - _list_->tail = NULL; \ - _list_->flag = CMC_FLAG_OK; \ - _list_->f_val = f_val; \ - _list_->alloc = alloc; \ - CMC_CALLBACKS_ASSIGN(_list_, callbacks); \ -\ - return _list_; \ - } \ -\ - void CMC_(PFX, _clear)(struct SNAME * _list_) \ - { \ - struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \ -\ - while (_list_->head != NULL) \ - { \ - _list_->head = _list_->head->next; \ -\ - if (_list_->f_val->free) \ - { \ - _list_->f_val->free(scan->value); \ - } \ -\ - _list_->alloc->free(scan); \ -\ - scan = _list_->head; \ - } \ -\ - _list_->count = 0; \ - _list_->head = NULL; \ - _list_->tail = NULL; \ - _list_->flag = CMC_FLAG_OK; \ - } \ -\ - void CMC_(PFX, _free)(struct SNAME * _list_) \ - { \ - CMC_(PFX, _clear)(_list_); \ -\ - _list_->alloc->free(_list_); \ - } \ -\ - void CMC_(PFX, _customize)(struct SNAME * _list_, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - if (!alloc) \ - _list_->alloc = &cmc_alloc_node_default; \ - else \ - _list_->alloc = alloc; \ -\ - CMC_CALLBACKS_ASSIGN(_list_, callbacks); \ -\ - _list_->flag = CMC_FLAG_OK; \ - } \ -\ - bool CMC_(PFX, _push_front)(struct SNAME * _list_, V value) \ - { \ - struct CMC_DEF_NODE(SNAME) *_node_ = CMC_(PFX, _new_node)(_list_, value); \ -\ - if (!_node_) \ - return false; \ -\ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->head = _node_; \ - _list_->tail = _node_; \ - } \ - else \ - { \ - _node_->next = _list_->head; \ - _list_->head->prev = _node_; \ - _list_->head = _node_; \ - } \ -\ - _list_->count++; \ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, create); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _push_at)(struct SNAME * _list_, V value, size_t index) \ - { \ - if (index > _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return false; \ - } \ -\ - if (index == 0) \ - { \ - return CMC_(PFX, _push_front)(_list_, value); \ - } \ - else if (index == _list_->count) \ - { \ - return CMC_(PFX, _push_back)(_list_, value); \ - } \ -\ - struct CMC_DEF_NODE(SNAME) *_node_ = CMC_(PFX, _new_node)(_list_, value); \ -\ - if (!_node_) \ - return false; \ -\ - struct CMC_DEF_NODE(SNAME) *scan = CMC_(PFX, _get_node)(_list_, index - 1); \ -\ - _node_->next = scan->next; \ - _node_->prev = scan; \ - _node_->next->prev = _node_; \ - _node_->prev->next = _node_; \ -\ - _list_->count++; \ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, create); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _push_back)(struct SNAME * _list_, V value) \ - { \ - struct CMC_DEF_NODE(SNAME) *_node_ = CMC_(PFX, _new_node)(_list_, value); \ -\ - if (!_node_) \ - return false; \ -\ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->head = _node_; \ - _list_->tail = _node_; \ - } \ - else \ - { \ - _node_->prev = _list_->tail; \ - _list_->tail->next = _node_; \ - _list_->tail = _node_; \ - } \ -\ - _list_->count++; \ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, create); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _pop_front)(struct SNAME * _list_) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - struct CMC_DEF_NODE(SNAME) *_node_ = _list_->head; \ - _list_->head = _list_->head->next; \ -\ - _list_->alloc->free(_node_); \ -\ - if (_list_->head == NULL) \ - _list_->tail = NULL; \ - else \ - _list_->head->prev = NULL; \ -\ - _list_->count--; \ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, delete); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _pop_at)(struct SNAME * _list_, size_t index) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - if (index >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return false; \ - } \ -\ - if (index == 0) \ - { \ - return CMC_(PFX, _pop_front)(_list_); \ - } \ - else if (index == _list_->count - 1) \ - { \ - return CMC_(PFX, _pop_back)(_list_); \ - } \ -\ - struct CMC_DEF_NODE(SNAME) *_node_ = CMC_(PFX, _get_node)(_list_, index); \ -\ - if (!_node_) \ - return false; \ -\ - _node_->next->prev = _node_->prev; \ - _node_->prev->next = _node_->next; \ -\ - _list_->alloc->free(_node_); \ -\ - _list_->count--; \ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, delete); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _pop_back)(struct SNAME * _list_) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - struct CMC_DEF_NODE(SNAME) *_node_ = _list_->tail; \ - _list_->tail = _list_->tail->prev; \ -\ - _list_->alloc->free(_node_); \ -\ - if (_list_->tail == NULL) \ - _list_->head = NULL; \ - else \ - _list_->tail->next = NULL; \ -\ - _list_->count--; \ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, delete); \ -\ - return true; \ - } \ -\ - V CMC_(PFX, _front)(struct SNAME * _list_) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ -\ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, read); \ -\ - return _list_->head->value; \ - } \ -\ - V CMC_(PFX, _get)(struct SNAME * _list_, size_t index) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ -\ - if (index >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return (V){ 0 }; \ - } \ -\ - struct CMC_DEF_NODE(SNAME) *scan = CMC_(PFX, _get_node)(_list_, index); \ -\ - if (scan == NULL) \ - return (V){ 0 }; \ -\ - CMC_CALLBACKS_CALL(_list_, read); \ -\ - return scan->value; \ - } \ -\ - V *CMC_(PFX, _get_ref)(struct SNAME * _list_, size_t index) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return NULL; \ - } \ -\ - if (index >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return NULL; \ - } \ -\ - struct CMC_DEF_NODE(SNAME) *scan = CMC_(PFX, _get_node)(_list_, index); \ -\ - if (scan == NULL) \ - return NULL; \ -\ - CMC_CALLBACKS_CALL(_list_, read); \ -\ - return &(scan->value); \ - } \ -\ - V CMC_(PFX, _back)(struct SNAME * _list_) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ -\ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, read); \ -\ - return _list_->tail->value; \ - } \ -\ - bool CMC_(PFX, _contains)(struct SNAME * _list_, V value) \ - { \ - _list_->flag = CMC_FLAG_OK; \ -\ - bool result = false; \ -\ - struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \ -\ - while (scan != NULL) \ - { \ - if (_list_->f_val->cmp(scan->value, value) == 0) \ - { \ - result = true; \ - break; \ - } \ -\ - scan = scan->next; \ - } \ -\ - CMC_CALLBACKS_CALL(_list_, read); \ -\ - return result; \ - } \ -\ - bool CMC_(PFX, _empty)(struct SNAME * _list_) \ - { \ - return _list_->count == 0; \ - } \ -\ - size_t CMC_(PFX, _count)(struct SNAME * _list_) \ - { \ - return _list_->count; \ - } \ -\ - int CMC_(PFX, _flag)(struct SNAME * _list_) \ - { \ - return _list_->flag; \ - } \ -\ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_) \ - { \ - struct SNAME *result = CMC_(PFX, _new_custom)(_list_->f_val, _list_->alloc, NULL); \ -\ - if (!result) \ - return NULL; \ -\ - CMC_CALLBACKS_ASSIGN(result, _list_->callbacks); \ -\ - struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \ -\ - while (scan != NULL) \ - { \ - /* This allocation should never fail since it might not be */ \ - /* possible to recover from it. That is why it isn't checked */ \ - struct CMC_DEF_NODE(SNAME) * new_node; \ -\ - if (_list_->f_val->cpy) \ - new_node = CMC_(PFX, _new_node)(_list_, _list_->f_val->cpy(scan->value)); \ - else \ - new_node = CMC_(PFX, _new_node)(_list_, scan->value); \ -\ - if (!result->head) \ - { \ - result->head = new_node; \ - result->tail = new_node; \ - } \ - else \ - { \ - new_node->prev = result->tail; \ - result->tail->next = new_node; \ - result->tail = new_node; \ - } \ -\ - scan = scan->next; \ - } \ -\ - result->count = _list_->count; \ -\ - _list_->flag = CMC_FLAG_OK; \ -\ - return result; \ - } \ -\ - bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_) \ - { \ - _list1_->flag = CMC_FLAG_OK; \ - _list2_->flag = CMC_FLAG_OK; \ -\ - if (_list1_->count != _list2_->count) \ - return false; \ -\ - struct CMC_DEF_NODE(SNAME) *scan1 = _list1_->head; \ - struct CMC_DEF_NODE(SNAME) *scan2 = _list2_->head; \ -\ - while (scan1 != NULL && scan2 != NULL) \ - { \ - if (_list1_->f_val->cmp(scan1->value, scan2->value) != 0) \ - return false; \ -\ - scan1 = scan1->next; \ - scan2 = scan2->next; \ - } \ -\ - return true; \ - } - -#endif /* CMC_CMC_LINKEDLIST_H */ diff --git a/src/cmc_list.h b/src/cmc_list.h deleted file mode 100644 index 3e25c0a..0000000 --- a/src/cmc_list.h +++ /dev/null @@ -1,643 +0,0 @@ -/** - * Copyright (c) 2019 Leonardo Vencovsky - * - * This file is part of the C Macro Collections Libray. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * cmc_list.h - * - * Creation Date: 12/02/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -/** - * List - * - * A List is a Dynamic Array that store its elements contiguously. It has an - * internal buffer that is pre-allocated with a greater capacity than necessary - * in order to foresee new elements being added. The items can be added at both - * ends of the list and at the middle (with a given index). - * - * Insertions at the start are more costly as it is necessary to shift all - * elements one position to the right to give space to a new element being added - * at index 0. Insertions at the end are instantaneous as long as there is - * enough space in the buffer. Insertions at the middle will be based on an - * index. The index represents where the element being added will be located - * once the operation ends. This operation might also need to shift elements. It - * is also possible to add arrays of elements in the list. - * - * When the buffer is filled, it is reallocated with a greater capacity, usually - * being doubled. - * - * Removing elements follows the same principle. Removing the front element will - * require to shift all other elements one position to the left, thus being - * slower than removing from the end in which is done in constant time. Removing - * elements in the middle of the list will also require shifting elements to the - * left. Is is also possible to remove a range of elements or extract them, - * creating a new list with the removed items. - * - * The iterator is a simple structure that is capable of going back and - * forwards. Any modifications to the target list during iteration is considered - * undefined behavior. Its sole purpose is to facilitate navigation through a - * list. - */ - -#ifndef CMC_CMC_LIST_H -#define CMC_CMC_LIST_H - -/* ------------------------------------------------------------------------- - * Core functionalities of the C Macro Collections Library - * ------------------------------------------------------------------------- */ -#include "cor_core.h" - -/** - * Core List implementation - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_CMC_LIST_CORE(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_CMC_LIST_CORE_, ACCESS), CMC_(_, FILE))(PARAMS) - -/* PRIVATE or PUBLIC solver */ -#define CMC_CMC_LIST_CORE_PUBLIC_HEADER(PARAMS) \ - CMC_CMC_LIST_CORE_STRUCT(PARAMS) \ - CMC_CMC_LIST_CORE_HEADER(PARAMS) - -#define CMC_CMC_LIST_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_LIST_CORE_SOURCE(PARAMS) - -#define CMC_CMC_LIST_CORE_PRIVATE_HEADER(PARAMS) \ - struct CMC_PARAM_SNAME(PARAMS); \ - CMC_CMC_LIST_CORE_HEADER(PARAMS) - -#define CMC_CMC_LIST_CORE_PRIVATE_SOURCE(PARAMS) \ - CMC_CMC_LIST_CORE_STRUCT(PARAMS) \ - CMC_CMC_LIST_CORE_SOURCE(PARAMS) - -/* Lowest level API */ -#define CMC_CMC_LIST_CORE_STRUCT(PARAMS) \ - CMC_CMC_LIST_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_CMC_LIST_CORE_HEADER(PARAMS) \ - CMC_CMC_LIST_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_CMC_LIST_CORE_SOURCE(PARAMS) \ - CMC_CMC_LIST_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -/* ------------------------------------------------------------------------- - * Struct - * ------------------------------------------------------------------------- */ -#define CMC_CMC_LIST_CORE_STRUCT_(PFX, SNAME, V) \ -\ - /* List Structure */ \ - struct SNAME \ - { \ - /* Dynamic array of elements */ \ - V *buffer; \ -\ - /* Current array capacity */ \ - size_t capacity; \ -\ - /* Current amount of elements */ \ - size_t count; \ -\ - /* Flags indicating errors or success */ \ - int flag; \ -\ - /* Value function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ -\ - /* Custom allocation functions */ \ - struct CMC_ALLOC_NODE_NAME *alloc; \ -\ - /* Custom callback functions */ \ - CMC_CALLBACKS_DECL; \ - }; - -/* ------------------------------------------------------------------------- - * Header - * ------------------------------------------------------------------------- */ -#define CMC_CMC_LIST_CORE_HEADER_(PFX, SNAME, V) \ -\ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(V); \ -\ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(V); \ -\ - /* To string function */ \ - CMC_DEF_FTAB_STR(V); \ -\ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(V); \ -\ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(V); \ -\ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(V); \ - }; \ -\ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks); \ - void CMC_(PFX, _clear)(struct SNAME * _list_); \ - void CMC_(PFX, _free)(struct SNAME * _list_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _list_, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _push_front)(struct SNAME * _list_, V value); \ - bool CMC_(PFX, _push_at)(struct SNAME * _list_, V value, size_t index); \ - bool CMC_(PFX, _push_back)(struct SNAME * _list_, V value); \ - bool CMC_(PFX, _pop_front)(struct SNAME * _list_); \ - bool CMC_(PFX, _pop_at)(struct SNAME * _list_, size_t index); \ - bool CMC_(PFX, _pop_back)(struct SNAME * _list_); \ - /* Element Access */ \ - V CMC_(PFX, _front)(struct SNAME * _list_); \ - V CMC_(PFX, _get)(struct SNAME * _list_, size_t index); \ - V *CMC_(PFX, _get_ref)(struct SNAME * _list_, size_t index); \ - V CMC_(PFX, _back)(struct SNAME * _list_); \ - size_t CMC_(PFX, _index_of)(struct SNAME * _list_, V value, bool from_start); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _list_, V value); \ - bool CMC_(PFX, _empty)(struct SNAME * _list_); \ - bool CMC_(PFX, _full)(struct SNAME * _list_); \ - size_t CMC_(PFX, _count)(struct SNAME * _list_); \ - bool CMC_(PFX, _fits)(struct SNAME * _list_, size_t size); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _list_); \ - int CMC_(PFX, _flag)(struct SNAME * _list_); \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _list_, size_t capacity); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_); \ - bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_); - -/* ------------------------------------------------------------------------- - * Source - * ------------------------------------------------------------------------- */ -#define CMC_CMC_LIST_CORE_SOURCE_(PFX, SNAME, V) \ -\ - /* Implementation Detail Functions */ \ - /* None */ \ -\ - struct SNAME *CMC_(PFX, _new)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - return CMC_(PFX, _new_custom)(capacity, f_val, NULL, NULL); \ - } \ -\ - struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - if (capacity < 1) \ - return NULL; \ -\ - if (!f_val) \ - return NULL; \ -\ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ -\ - struct SNAME *_list_ = alloc->malloc(sizeof(struct SNAME)); \ -\ - if (!_list_) \ - return NULL; \ -\ - _list_->buffer = alloc->calloc(capacity, sizeof(V)); \ -\ - if (!_list_->buffer) \ - { \ - alloc->free(_list_); \ - return NULL; \ - } \ -\ - _list_->capacity = capacity; \ - _list_->count = 0; \ - _list_->flag = CMC_FLAG_OK; \ - _list_->f_val = f_val; \ - _list_->alloc = alloc; \ - CMC_CALLBACKS_ASSIGN(_list_, callbacks); \ -\ - return _list_; \ - } \ -\ - void CMC_(PFX, _clear)(struct SNAME * _list_) \ - { \ - if (_list_->f_val->free) \ - { \ - for (size_t i = 0; i < _list_->count; i++) \ - _list_->f_val->free(_list_->buffer[i]); \ - } \ -\ - memset(_list_->buffer, 0, sizeof(V) * _list_->capacity); \ -\ - _list_->count = 0; \ - _list_->flag = CMC_FLAG_OK; \ - } \ -\ - void CMC_(PFX, _free)(struct SNAME * _list_) \ - { \ - if (_list_->f_val->free) \ - { \ - for (size_t i = 0; i < _list_->count; i++) \ - _list_->f_val->free(_list_->buffer[i]); \ - } \ -\ - _list_->alloc->free(_list_->buffer); \ - _list_->alloc->free(_list_); \ - } \ -\ - void CMC_(PFX, _customize)(struct SNAME * _list_, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - if (!alloc) \ - _list_->alloc = &cmc_alloc_node_default; \ - else \ - _list_->alloc = alloc; \ -\ - CMC_CALLBACKS_ASSIGN(_list_, callbacks); \ -\ - _list_->flag = CMC_FLAG_OK; \ - } \ -\ - bool CMC_(PFX, _push_front)(struct SNAME * _list_, V value) \ - { \ - if (CMC_(PFX, _full)(_list_)) \ - { \ - if (!CMC_(PFX, _resize)(_list_, _list_->count * 2)) \ - return false; \ - } \ -\ - if (!CMC_(PFX, _empty)(_list_)) \ - { \ - memmove(_list_->buffer + 1, _list_->buffer, _list_->count * sizeof(V)); \ - } \ -\ - _list_->buffer[0] = value; \ -\ - _list_->count++; \ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, create); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _push_at)(struct SNAME * _list_, V value, size_t index) \ - { \ - if (index > _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return false; \ - } \ -\ - if (CMC_(PFX, _full)(_list_)) \ - { \ - if (!CMC_(PFX, _resize)(_list_, _list_->count * 2)) \ - return false; \ - } \ -\ - memmove(_list_->buffer + index + 1, _list_->buffer + index, (_list_->count - index) * sizeof(V)); \ -\ - _list_->buffer[index] = value; \ - _list_->count++; \ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, create); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _push_back)(struct SNAME * _list_, V value) \ - { \ - if (CMC_(PFX, _full)(_list_)) \ - { \ - if (!CMC_(PFX, _resize)(_list_, _list_->count * 2)) \ - return false; \ - } \ -\ - _list_->buffer[_list_->count++] = value; \ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, create); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _pop_front)(struct SNAME * _list_) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - memmove(_list_->buffer, _list_->buffer + 1, (_list_->count - 1) * sizeof(V)); \ -\ - _list_->buffer[--_list_->count] = (V){ 0 }; \ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, delete); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _pop_at)(struct SNAME * _list_, size_t index) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - if (index >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return false; \ - } \ -\ - memmove(_list_->buffer + index, _list_->buffer + index + 1, (_list_->count - index - 1) * sizeof(V)); \ -\ - _list_->buffer[--_list_->count] = (V){ 0 }; \ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, delete); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _pop_back)(struct SNAME * _list_) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - return false; \ -\ - _list_->buffer[--_list_->count] = (V){ 0 }; \ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, delete); \ -\ - return true; \ - } \ -\ - V CMC_(PFX, _front)(struct SNAME * _list_) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ -\ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, read); \ -\ - return _list_->buffer[0]; \ - } \ -\ - V CMC_(PFX, _get)(struct SNAME * _list_, size_t index) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ -\ - if (index >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return (V){ 0 }; \ - } \ -\ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, read); \ -\ - return _list_->buffer[index]; \ - } \ -\ - V *CMC_(PFX, _get_ref)(struct SNAME * _list_, size_t index) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return NULL; \ - } \ -\ - if (index >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return NULL; \ - } \ -\ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, read); \ -\ - return &(_list_->buffer[index]); \ - } \ -\ - V CMC_(PFX, _back)(struct SNAME * _list_) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ -\ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, read); \ -\ - return _list_->buffer[_list_->count - 1]; \ - } \ -\ - size_t CMC_(PFX, _index_of)(struct SNAME * _list_, V value, bool from_start) \ - { \ - _list_->flag = CMC_FLAG_OK; \ -\ - size_t result = _list_->count; \ -\ - if (from_start) \ - { \ - for (size_t i = 0; i < _list_->count; i++) \ - { \ - if (_list_->f_val->cmp(_list_->buffer[i], value) == 0) \ - { \ - result = i; \ - break; \ - } \ - } \ - } \ - else \ - { \ - for (size_t i = _list_->count; i > 0; i--) \ - { \ - if (_list_->f_val->cmp(_list_->buffer[i - 1], value) == 0) \ - { \ - result = i - 1; \ - break; \ - } \ - } \ - } \ -\ - CMC_CALLBACKS_CALL(_list_, read); \ -\ - return result; \ - } \ -\ - bool CMC_(PFX, _contains)(struct SNAME * _list_, V value) \ - { \ - _list_->flag = CMC_FLAG_OK; \ -\ - bool result = false; \ -\ - for (size_t i = 0; i < _list_->count; i++) \ - { \ - if (_list_->f_val->cmp(_list_->buffer[i], value) == 0) \ - { \ - result = true; \ - break; \ - } \ - } \ -\ - CMC_CALLBACKS_CALL(_list_, read); \ -\ - return result; \ - } \ -\ - bool CMC_(PFX, _empty)(struct SNAME * _list_) \ - { \ - return _list_->count == 0; \ - } \ -\ - bool CMC_(PFX, _full)(struct SNAME * _list_) \ - { \ - return _list_->count >= _list_->capacity; \ - } \ -\ - size_t CMC_(PFX, _count)(struct SNAME * _list_) \ - { \ - return _list_->count; \ - } \ -\ - bool CMC_(PFX, _fits)(struct SNAME * _list_, size_t size) \ - { \ - return _list_->count + size <= _list_->capacity; \ - } \ -\ - size_t CMC_(PFX, _capacity)(struct SNAME * _list_) \ - { \ - return _list_->capacity; \ - } \ -\ - int CMC_(PFX, _flag)(struct SNAME * _list_) \ - { \ - return _list_->flag; \ - } \ -\ - bool CMC_(PFX, _resize)(struct SNAME * _list_, size_t capacity) \ - { \ - _list_->flag = CMC_FLAG_OK; \ -\ - if (_list_->capacity == capacity) \ - return true; \ -\ - if (capacity < _list_->count) \ - { \ - _list_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ -\ - V *new_buffer = _list_->alloc->realloc(_list_->buffer, sizeof(V) * capacity); \ -\ - if (!new_buffer) \ - { \ - _list_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ -\ - /* TODO zero out new slots */ \ -\ - _list_->buffer = new_buffer; \ - _list_->capacity = capacity; \ -\ - CMC_CALLBACKS_CALL(_list_, resize); \ -\ - return true; \ - } \ -\ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_) \ - { \ - struct SNAME *result = CMC_(PFX, _new_custom)(_list_->capacity, _list_->f_val, _list_->alloc, NULL); \ -\ - if (!result) \ - { \ - _list_->flag = CMC_FLAG_ALLOC; \ - return NULL; \ - } \ -\ - CMC_CALLBACKS_ASSIGN(result, _list_->callbacks); \ -\ - if (_list_->f_val->cpy) \ - { \ - for (size_t i = 0; i < _list_->count; i++) \ - result->buffer[i] = _list_->f_val->cpy(_list_->buffer[i]); \ - } \ - else \ - memcpy(result->buffer, _list_->buffer, sizeof(V) * _list_->count); \ -\ - result->count = _list_->count; \ -\ - _list_->flag = CMC_FLAG_OK; \ -\ - return result; \ - } \ -\ - bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_) \ - { \ - _list1_->flag = CMC_FLAG_OK; \ - _list2_->flag = CMC_FLAG_OK; \ -\ - if (_list1_->count != _list2_->count) \ - return false; \ -\ - for (size_t i = 0; i < _list1_->count; i++) \ - { \ - if (0 != _list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i])) \ - return false; \ - } \ -\ - return true; \ - } - -#endif /* CMC_CMC_LIST_H */ diff --git a/src/cmc_queue.h b/src/cmc_queue.h deleted file mode 100644 index f9aaf3a..0000000 --- a/src/cmc_queue.h +++ /dev/null @@ -1,505 +0,0 @@ -/** - * Copyright (c) 2019 Leonardo Vencovsky - * - * This file is part of the C Macro Collections Libray. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * cmc_queue.h - * - * Creation Date: 15/02/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -/** - * Queue - * - * A Queue is a First-In First-out (or Last-in Last-out) data structure. It is - * a Dynamic Circular Array where elements are added from one end of the array - * and removed from the other end. The circular array here (also known as - * circular buffer or ring buffer) is very important so that both adding and - * removing elements from the Queue are done instantly. The array is linear but - * with the modulo operator it is treated as a circular sequence of elements. - * - * If the Queue was implemented as a regular Dynamic Array, when adding or - * removing an element at the front, it would be necessary to shift all elements - * currently present in the Queue and this would add up a lot of computing time. - * Shifting `100000` elements in memory by one position every time an element is - * added to the Queue is simply not efficient. - * - * The Queue has two ends. The `front` and `back`. In this implementation all - * elements are added to the back of the Queue and removed from the front, which - * is more or less how queues work in real life. Unlike a Stack that only has - * operations at one end of the buffer, the Queue needs to be implemented as a - * circular array in order to quickly add or remove elements. - * - * The Queue has three main functions: `enqueue` which adds an element to the - * Queue; `dequeue` which removes an element from the Queue; and `peek` which - * return the element at the front of the Queue, that is, the next element to - * be removed from it. - * - * The Queue is used in many applications where a resource is shared among - * multiple consumers and the Queue is responsible for scheduling the access to - * the resource. - */ - -#ifndef CMC_CMC_QUEUE_H -#define CMC_CMC_QUEUE_H - -/* ------------------------------------------------------------------------- - * Core functionalities of the C Macro Collections Library - * ------------------------------------------------------------------------- */ -#include "cor_core.h" - -/** - * Core Queue implementation - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_CMC_QUEUE_CORE(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_CMC_QUEUE_CORE_, ACCESS), CMC_(_, FILE))(PARAMS) - -/* PRIVATE or PUBLIC solver */ -#define CMC_CMC_QUEUE_CORE_PUBLIC_HEADER(PARAMS) \ - CMC_CMC_QUEUE_CORE_STRUCT(PARAMS) \ - CMC_CMC_QUEUE_CORE_HEADER(PARAMS) - -#define CMC_CMC_QUEUE_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_QUEUE_CORE_SOURCE(PARAMS) - -#define CMC_CMC_QUEUE_CORE_PRIVATE_HEADER(PARAMS) \ - struct CMC_PARAM_SNAME(PARAMS); \ - CMC_CMC_QUEUE_CORE_HEADER(PARAMS) - -#define CMC_CMC_QUEUE_CORE_PRIVATE_SOURCE(PARAMS) \ - CMC_CMC_QUEUE_CORE_STRUCT(PARAMS) \ - CMC_CMC_QUEUE_CORE_SOURCE(PARAMS) - -/* Lowest level API */ -#define CMC_CMC_QUEUE_CORE_STRUCT(PARAMS) \ - CMC_CMC_QUEUE_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_CMC_QUEUE_CORE_HEADER(PARAMS) \ - CMC_CMC_QUEUE_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_CMC_QUEUE_CORE_SOURCE(PARAMS) \ - CMC_CMC_QUEUE_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -/* ------------------------------------------------------------------------- - * Struct - * ------------------------------------------------------------------------- */ -#define CMC_CMC_QUEUE_CORE_STRUCT_(PFX, SNAME, V) \ -\ - /* Queue Structure */ \ - struct SNAME \ - { \ - /* Dynamic circular array of elements */ \ - V *buffer; \ -\ - /* Current circular array capacity */ \ - size_t capacity; \ -\ - /* Current amount of elements */ \ - size_t count; \ -\ - /* Index representing the front of the queue */ \ - size_t front; \ -\ - /* Index representing the back of the queue */ \ - size_t back; \ -\ - /* Flags indicating errors or success */ \ - int flag; \ -\ - /* Value function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ -\ - /* Custom allocation functions */ \ - struct CMC_ALLOC_NODE_NAME *alloc; \ -\ - /* Custom callback functions */ \ - CMC_CALLBACKS_DECL; \ - }; - -/* ------------------------------------------------------------------------- - * Header - * ------------------------------------------------------------------------- */ -#define CMC_CMC_QUEUE_CORE_HEADER_(PFX, SNAME, V) \ -\ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(V); \ -\ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(V); \ -\ - /* To string function */ \ - CMC_DEF_FTAB_STR(V); \ -\ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(V); \ -\ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(V); \ -\ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(V); \ - }; \ -\ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks); \ - void CMC_(PFX, _clear)(struct SNAME * _queue_); \ - void CMC_(PFX, _free)(struct SNAME * _queue_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _queue_, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _enqueue)(struct SNAME * _queue_, V value); \ - bool CMC_(PFX, _dequeue)(struct SNAME * _queue_); \ - /* Element Access */ \ - V CMC_(PFX, _peek)(struct SNAME * _queue_); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _queue_, V value); \ - bool CMC_(PFX, _empty)(struct SNAME * _queue_); \ - bool CMC_(PFX, _full)(struct SNAME * _queue_); \ - size_t CMC_(PFX, _count)(struct SNAME * _queue_); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _queue_); \ - int CMC_(PFX, _flag)(struct SNAME * _queue_); \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _queue_, size_t capacity); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _queue_); \ - bool CMC_(PFX, _equals)(struct SNAME * _queue1_, struct SNAME * _queue2_); - -/* ------------------------------------------------------------------------- - * Source - * ------------------------------------------------------------------------- */ -#define CMC_CMC_QUEUE_CORE_SOURCE_(PFX, SNAME, V) \ -\ - /* Implementation Detail Functions */ \ - /* None */ \ -\ - struct SNAME *CMC_(PFX, _new)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - return CMC_(PFX, _new_custom)(capacity, f_val, NULL, NULL); \ - } \ -\ - struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - if (capacity < 1) \ - return NULL; \ -\ - if (!f_val) \ - return NULL; \ -\ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ -\ - struct SNAME *_queue_ = alloc->malloc(sizeof(struct SNAME)); \ -\ - if (!_queue_) \ - return NULL; \ -\ - _queue_->buffer = alloc->calloc(capacity, sizeof(V)); \ -\ - if (!_queue_->buffer) \ - { \ - alloc->free(_queue_); \ - return NULL; \ - } \ -\ - _queue_->capacity = capacity; \ - _queue_->count = 0; \ - _queue_->front = 0; \ - _queue_->back = 0; \ - _queue_->flag = CMC_FLAG_OK; \ - _queue_->f_val = f_val; \ - _queue_->alloc = alloc; \ - CMC_CALLBACKS_ASSIGN(_queue_, callbacks); \ -\ - return _queue_; \ - } \ -\ - void CMC_(PFX, _clear)(struct SNAME * _queue_) \ - { \ - if (_queue_->f_val->free) \ - { \ - for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ - { \ - _queue_->f_val->free(_queue_->buffer[i]); \ -\ - i = (i + 1) % _queue_->capacity; \ - } \ - } \ -\ - memset(_queue_->buffer, 0, sizeof(V) * _queue_->capacity); \ -\ - _queue_->count = 0; \ - _queue_->front = 0; \ - _queue_->back = 0; \ - _queue_->flag = CMC_FLAG_OK; \ - } \ -\ - void CMC_(PFX, _free)(struct SNAME * _queue_) \ - { \ - if (_queue_->f_val->free) \ - { \ - for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ - { \ - _queue_->f_val->free(_queue_->buffer[i]); \ -\ - i = (i + 1) % _queue_->capacity; \ - } \ - } \ -\ - _queue_->alloc->free(_queue_->buffer); \ - _queue_->alloc->free(_queue_); \ - } \ -\ - void CMC_(PFX, _customize)(struct SNAME * _queue_, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - if (!alloc) \ - _queue_->alloc = &cmc_alloc_node_default; \ - else \ - _queue_->alloc = alloc; \ -\ - CMC_CALLBACKS_ASSIGN(_queue_, callbacks); \ -\ - _queue_->flag = CMC_FLAG_OK; \ - } \ -\ - bool CMC_(PFX, _enqueue)(struct SNAME * _queue_, V value) \ - { \ - if (CMC_(PFX, _full)(_queue_)) \ - { \ - if (!CMC_(PFX, _resize)(_queue_, _queue_->capacity * 2)) \ - return false; \ - } \ -\ - _queue_->buffer[_queue_->back] = value; \ -\ - _queue_->back = (_queue_->back == _queue_->capacity - 1) ? 0 : _queue_->back + 1; \ - _queue_->count++; \ - _queue_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_queue_, create); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _dequeue)(struct SNAME * _queue_) \ - { \ - if (CMC_(PFX, _empty)(_queue_)) \ - { \ - _queue_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - _queue_->buffer[_queue_->front] = (V){ 0 }; \ -\ - _queue_->front = (_queue_->front == _queue_->capacity - 1) ? 0 : _queue_->front + 1; \ - _queue_->count--; \ - _queue_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_queue_, delete); \ -\ - return true; \ - } \ -\ - V CMC_(PFX, _peek)(struct SNAME * _queue_) \ - { \ - if (CMC_(PFX, _empty)(_queue_)) \ - { \ - _queue_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ -\ - _queue_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_queue_, read); \ -\ - return _queue_->buffer[_queue_->front]; \ - } \ -\ - bool CMC_(PFX, _contains)(struct SNAME * _queue_, V value) \ - { \ - _queue_->flag = CMC_FLAG_OK; \ -\ - bool result = false; \ -\ - for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ - { \ - if (_queue_->f_val->cmp(_queue_->buffer[i], value) == 0) \ - { \ - result = true; \ - break; \ - } \ -\ - i = (i + 1) % _queue_->capacity; \ - } \ -\ - CMC_CALLBACKS_CALL(_queue_, read); \ -\ - return result; \ - } \ -\ - bool CMC_(PFX, _empty)(struct SNAME * _queue_) \ - { \ - return _queue_->count == 0; \ - } \ -\ - bool CMC_(PFX, _full)(struct SNAME * _queue_) \ - { \ - return _queue_->count >= _queue_->capacity; \ - } \ -\ - size_t CMC_(PFX, _count)(struct SNAME * _queue_) \ - { \ - return _queue_->count; \ - } \ -\ - size_t CMC_(PFX, _capacity)(struct SNAME * _queue_) \ - { \ - return _queue_->capacity; \ - } \ -\ - int CMC_(PFX, _flag)(struct SNAME * _queue_) \ - { \ - return _queue_->flag; \ - } \ -\ - bool CMC_(PFX, _resize)(struct SNAME * _queue_, size_t capacity) \ - { \ - if (_queue_->capacity == capacity) \ - goto success; \ -\ - if (capacity < _queue_->count) \ - { \ - _queue_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ -\ - V *new_buffer = _queue_->alloc->malloc(sizeof(V) * capacity); \ -\ - if (!new_buffer) \ - { \ - _queue_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ -\ - for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ - { \ - new_buffer[j] = _queue_->buffer[i]; \ -\ - i = (i + 1) % _queue_->capacity; \ - } \ -\ - _queue_->alloc->free(_queue_->buffer); \ -\ - _queue_->buffer = new_buffer; \ - _queue_->capacity = capacity; \ - _queue_->front = 0; \ - _queue_->back = _queue_->count; \ -\ - success: \ -\ - _queue_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_queue_, resize); \ -\ - return true; \ - } \ -\ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _queue_) \ - { \ - struct SNAME *result = CMC_(PFX, _new_custom)(_queue_->capacity, _queue_->f_val, _queue_->alloc, NULL); \ -\ - if (!result) \ - { \ - _queue_->flag = CMC_FLAG_ERROR; \ - return NULL; \ - } \ -\ - CMC_CALLBACKS_ASSIGN(result, _queue_->callbacks); \ -\ - if (_queue_->f_val->cpy) \ - { \ - for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ - { \ - result->buffer[j] = _queue_->f_val->cpy(_queue_->buffer[i]); \ -\ - i = (i + 1) % _queue_->capacity; \ - } \ - } \ - else \ - { \ - for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ - { \ - result->buffer[j] = _queue_->buffer[i]; \ -\ - i = (i + 1) % _queue_->capacity; \ - } \ - } \ -\ - result->count = _queue_->count; \ - result->front = 0; \ - result->back = _queue_->count; \ -\ - _queue_->flag = CMC_FLAG_OK; \ -\ - return result; \ - } \ -\ - bool CMC_(PFX, _equals)(struct SNAME * _queue1_, struct SNAME * _queue2_) \ - { \ - _queue1_->flag = CMC_FLAG_OK; \ - _queue2_->flag = CMC_FLAG_OK; \ -\ - if (_queue1_->count != _queue2_->count) \ - return false; \ -\ - size_t i, j, k; \ - for (i = _queue1_->front, j = _queue2_->front, k = 0; k < _queue1_->count; k++) \ - { \ - if (_queue1_->f_val->cmp(_queue1_->buffer[i], _queue2_->buffer[j]) != 0) \ - return false; \ -\ - i = (i + 1) % _queue1_->capacity; \ - j = (j + 1) % _queue2_->capacity; \ - } \ -\ - return true; \ - } - -#endif /* CMC_CMC_QUEUE_H */ diff --git a/src/cmc_sortedlist.h b/src/cmc_sortedlist.h deleted file mode 100644 index 4ccc9f5..0000000 --- a/src/cmc_sortedlist.h +++ /dev/null @@ -1,641 +0,0 @@ -/** - * Copyright (c) 2019 Leonardo Vencovsky - * - * This file is part of the C Macro Collections Libray. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * cmc_sortedlist.h - * - * Creation Date: 17/09/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -/** - * SortedList - * - * A sorted list is a dynamic array, meaning that you can store as many elements - * as you like and when its capacity is full, the buffer is reallocated. The - * elements are only sorted when a certain action requires that the array is - * sorted like accessing min() or max(). This prevents the array from being - * sorted after every insertion or removal. The array is sorted using a - * variation of quick sort that uses insertion sort for small partitions. - */ - -#ifndef CMC_CMC_SORTEDLIST_H -#define CMC_CMC_SORTEDLIST_H - -/* ------------------------------------------------------------------------- - * Core functionalities of the C Macro Collections Library - * ------------------------------------------------------------------------- */ -#include "cor_core.h" - -/** - * Core SortedList implementation - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_CMC_SORTEDLIST_CORE(ACCESS, FILE, PARAMS) \ - CMC_(CMC_(CMC_CMC_SORTEDLIST_CORE_, ACCESS), CMC_(_, FILE))(PARAMS) - -/* PRIVATE or PUBLIC solver */ -#define CMC_CMC_SORTEDLIST_CORE_PUBLIC_HEADER(PARAMS) \ - CMC_CMC_SORTEDLIST_CORE_STRUCT(PARAMS) \ - CMC_CMC_SORTEDLIST_CORE_HEADER(PARAMS) - -#define CMC_CMC_SORTEDLIST_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_SORTEDLIST_CORE_SOURCE(PARAMS) - -#define CMC_CMC_SORTEDLIST_CORE_PRIVATE_HEADER(PARAMS) \ - struct CMC_PARAM_SNAME(PARAMS); \ - CMC_CMC_SORTEDLIST_CORE_HEADER(PARAMS) - -#define CMC_CMC_SORTEDLIST_CORE_PRIVATE_SOURCE(PARAMS) \ - CMC_CMC_SORTEDLIST_CORE_STRUCT(PARAMS) \ - CMC_CMC_SORTEDLIST_CORE_SOURCE(PARAMS) - -/* Lowest level API */ -#define CMC_CMC_SORTEDLIST_CORE_STRUCT(PARAMS) \ - CMC_CMC_SORTEDLIST_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_CMC_SORTEDLIST_CORE_HEADER(PARAMS) \ - CMC_CMC_SORTEDLIST_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_CMC_SORTEDLIST_CORE_SOURCE(PARAMS) \ - CMC_CMC_SORTEDLIST_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -/* ------------------------------------------------------------------------- - * Struct - * ------------------------------------------------------------------------- */ -#define CMC_CMC_SORTEDLIST_CORE_STRUCT_(PFX, SNAME, V) \ -\ - /* List Structure */ \ - struct SNAME \ - { \ - /* Dynamic array of elements */ \ - V *buffer; \ -\ - /* Current array capacity */ \ - size_t capacity; \ -\ - /* Current amount of elements */ \ - size_t count; \ -\ - /* Flag if the list is sorted or not, used by lazy evaluation */ \ - bool is_sorted; \ -\ - /* Flags indicating errors or success */ \ - int flag; \ -\ - /* Value function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ -\ - /* Custom allocation functions */ \ - struct CMC_ALLOC_NODE_NAME *alloc; \ -\ - /* Custom callback functions */ \ - CMC_CALLBACKS_DECL; \ - }; - -/* ------------------------------------------------------------------------- - * Header - * ------------------------------------------------------------------------- */ -#define CMC_CMC_SORTEDLIST_CORE_HEADER_(PFX, SNAME, V) \ -\ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(V); \ -\ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(V); \ -\ - /* To string function */ \ - CMC_DEF_FTAB_STR(V); \ -\ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(V); \ -\ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(V); \ -\ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(V); \ - }; \ -\ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks); \ - void CMC_(PFX, _clear)(struct SNAME * _list_); \ - void CMC_(PFX, _free)(struct SNAME * _list_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _list_, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _insert)(struct SNAME * _list_, V value); \ - bool CMC_(PFX, _remove)(struct SNAME * _list_, size_t index); \ - /* Element Access */ \ - V CMC_(PFX, _max)(struct SNAME * _list_); \ - V CMC_(PFX, _min)(struct SNAME * _list_); \ - V CMC_(PFX, _get)(struct SNAME * _list_, size_t index); \ - size_t CMC_(PFX, _index_of)(struct SNAME * _list_, V value, bool from_start); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _list_, V value); \ - bool CMC_(PFX, _empty)(struct SNAME * _list_); \ - bool CMC_(PFX, _full)(struct SNAME * _list_); \ - size_t CMC_(PFX, _count)(struct SNAME * _list_); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _list_); \ - int CMC_(PFX, _flag)(struct SNAME * _list_); \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _list_, size_t capacity); \ - void CMC_(PFX, _sort)(struct SNAME * _list_); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_); \ - bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_); - -/* ------------------------------------------------------------------------- - * Source - * ------------------------------------------------------------------------- */ -#define CMC_CMC_SORTEDLIST_CORE_SOURCE_(PFX, SNAME, V) \ -\ - /* Implementation Detail Functions */ \ - static size_t CMC_(PFX, _impl_binary_search_first)(struct SNAME * _list_, V value); \ - static size_t CMC_(PFX, _impl_binary_search_last)(struct SNAME * _list_, V value); \ - void CMC_(PFX, _impl_sort_quicksort)(V * array, int (*cmp)(V, V), size_t low, size_t high); \ - void CMC_(PFX, _impl_sort_insertion)(V * array, int (*cmp)(V, V), size_t low, size_t high); \ -\ - struct SNAME *CMC_(PFX, _new)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - return CMC_(PFX, _new_custom)(capacity, f_val, NULL, NULL); \ - } \ -\ - struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - if (capacity < 1) \ - return NULL; \ -\ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ -\ - struct SNAME *_list_ = alloc->malloc(sizeof(struct SNAME)); \ -\ - if (!_list_) \ - return NULL; \ -\ - _list_->buffer = alloc->calloc(capacity, sizeof(V)); \ -\ - if (!_list_->buffer) \ - { \ - alloc->free(_list_); \ - return NULL; \ - } \ -\ - _list_->capacity = capacity; \ - _list_->count = 0; \ - _list_->is_sorted = false; \ - _list_->flag = CMC_FLAG_OK; \ - _list_->f_val = f_val; \ - _list_->alloc = alloc; \ - CMC_CALLBACKS_ASSIGN(_list_, callbacks); \ -\ - return _list_; \ - } \ -\ - void CMC_(PFX, _clear)(struct SNAME * _list_) \ - { \ - if (_list_->f_val->free) \ - { \ - for (size_t i = 0; i < _list_->count; i++) \ - _list_->f_val->free(_list_->buffer[i]); \ - } \ -\ - memset(_list_->buffer, 0, sizeof(V) * _list_->capacity); \ -\ - _list_->count = 0; \ - _list_->flag = CMC_FLAG_OK; \ - } \ -\ - void CMC_(PFX, _free)(struct SNAME * _list_) \ - { \ - if (_list_->f_val->free) \ - { \ - for (size_t i = 0; i < _list_->count; i++) \ - _list_->f_val->free(_list_->buffer[i]); \ - } \ -\ - _list_->alloc->free(_list_->buffer); \ - _list_->alloc->free(_list_); \ - } \ -\ - void CMC_(PFX, _customize)(struct SNAME * _list_, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - if (!alloc) \ - _list_->alloc = &cmc_alloc_node_default; \ - else \ - _list_->alloc = alloc; \ -\ - CMC_CALLBACKS_ASSIGN(_list_, callbacks); \ -\ - _list_->flag = CMC_FLAG_OK; \ - } \ -\ - bool CMC_(PFX, _insert)(struct SNAME * _list_, V value) \ - { \ - if (CMC_(PFX, _full)(_list_)) \ - { \ - if (!CMC_(PFX, _resize)(_list_, _list_->capacity * 2)) \ - return false; \ - } \ -\ - _list_->buffer[_list_->count++] = value; \ -\ - _list_->is_sorted = false; \ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, create); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _remove)(struct SNAME * _list_, size_t index) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - if (index >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return false; \ - } \ -\ - memmove(_list_->buffer + index, _list_->buffer + index + 1, (_list_->count - index) * sizeof(V)); \ -\ - _list_->buffer[--_list_->count] = (V){ 0 }; \ -\ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, delete); \ -\ - return true; \ - } \ -\ - V CMC_(PFX, _max)(struct SNAME * _list_) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ -\ - CMC_(PFX, _sort)(_list_); \ -\ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, read); \ -\ - return _list_->buffer[_list_->count - 1]; \ - } \ -\ - V CMC_(PFX, _min)(struct SNAME * _list_) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ -\ - CMC_(PFX, _sort)(_list_); \ -\ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, read); \ -\ - return _list_->buffer[0]; \ - } \ -\ - V CMC_(PFX, _get)(struct SNAME * _list_, size_t index) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ -\ - if (index >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return (V){ 0 }; \ - } \ -\ - CMC_(PFX, _sort)(_list_); \ -\ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, read); \ -\ - return _list_->buffer[index]; \ - } \ -\ - size_t CMC_(PFX, _index_of)(struct SNAME * _list_, V value, bool from_start) \ - { \ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_(PFX, _sort)(_list_); \ -\ - CMC_CALLBACKS_CALL(_list_, read); \ -\ - if (from_start) \ - { \ - return CMC_(PFX, _impl_binary_search_first)(_list_, value); \ - } \ -\ - return CMC_(PFX, _impl_binary_search_last)(_list_, value); \ - } \ -\ - bool CMC_(PFX, _contains)(struct SNAME * _list_, V value) \ - { \ - _list_->flag = CMC_FLAG_OK; \ -\ - if (CMC_(PFX, _empty)(_list_)) \ - return false; \ -\ - CMC_(PFX, _sort)(_list_); \ -\ - CMC_CALLBACKS_CALL(_list_, read); \ -\ - return CMC_(PFX, _impl_binary_search_first)(_list_, value) < _list_->count; \ - } \ -\ - bool CMC_(PFX, _empty)(struct SNAME * _list_) \ - { \ - return _list_->count == 0; \ - } \ -\ - bool CMC_(PFX, _full)(struct SNAME * _list_) \ - { \ - return _list_->count >= _list_->capacity; \ - } \ -\ - size_t CMC_(PFX, _count)(struct SNAME * _list_) \ - { \ - return _list_->count; \ - } \ -\ - size_t CMC_(PFX, _capacity)(struct SNAME * _list_) \ - { \ - return _list_->capacity; \ - } \ -\ - int CMC_(PFX, _flag)(struct SNAME * _list_) \ - { \ - return _list_->flag; \ - } \ -\ - bool CMC_(PFX, _resize)(struct SNAME * _list_, size_t capacity) \ - { \ - if (_list_->capacity == capacity) \ - goto success; \ -\ - if (capacity < _list_->count) \ - { \ - _list_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ -\ - V *new_buffer = _list_->alloc->realloc(_list_->buffer, sizeof(V) * capacity); \ -\ - if (!new_buffer) \ - { \ - _list_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ -\ - /* TODO zero out remaining slots */ \ -\ - _list_->buffer = new_buffer; \ - _list_->capacity = capacity; \ -\ - success: \ -\ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, resize); \ -\ - return true; \ - } \ -\ - void CMC_(PFX, _sort)(struct SNAME * _list_) \ - { \ - _list_->flag = CMC_FLAG_OK; \ -\ - if (!_list_->is_sorted && _list_->count > 1) \ - { \ - CMC_(PFX, _impl_sort_quicksort) \ - (_list_->buffer, _list_->f_val->cmp, 0, _list_->count - 1); \ -\ - _list_->is_sorted = true; \ - } \ - } \ -\ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_) \ - { \ - struct SNAME *result = CMC_(PFX, _new_custom)(_list_->capacity, _list_->f_val, _list_->alloc, NULL); \ -\ - if (!result) \ - { \ - _list_->flag = CMC_FLAG_ERROR; \ - return NULL; \ - } \ -\ - CMC_CALLBACKS_ASSIGN(result, _list_->callbacks); \ -\ - if (_list_->f_val->cpy) \ - { \ - for (size_t i = 0; i < _list_->count; i++) \ - result->buffer[i] = _list_->f_val->cpy(_list_->buffer[i]); \ - } \ - else \ - memcpy(result->buffer, _list_->buffer, sizeof(V) * _list_->count); \ -\ - result->count = _list_->count; \ -\ - _list_->flag = CMC_FLAG_OK; \ -\ - return result; \ - } \ -\ - bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_) \ - { \ - if (_list1_->count != _list2_->count) \ - return false; \ -\ - CMC_(PFX, _sort)(_list1_); \ - CMC_(PFX, _sort)(_list2_); \ -\ - for (size_t i = 0; i < _list1_->count; i++) \ - { \ - if (_list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i]) != 0) \ - return false; \ - } \ -\ - return true; \ - } \ -\ - static size_t CMC_(PFX, _impl_binary_search_first)(struct SNAME * _list_, V value) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - return 1; \ -\ - size_t L = 0; \ - size_t R = _list_->count; \ -\ - while (L < R) \ - { \ - size_t M = L + (R - L) / 2; \ -\ - if (_list_->f_val->cmp(_list_->buffer[M], value) < 0) \ - L = M + 1; \ - else \ - R = M; \ - } \ -\ - if (_list_->f_val->cmp(_list_->buffer[L], value) == 0) \ - return L; \ -\ - /* Not found */ \ - return _list_->count; \ - } \ -\ - static size_t CMC_(PFX, _impl_binary_search_last)(struct SNAME * _list_, V value) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - return 1; \ -\ - size_t L = 0; \ - size_t R = _list_->count; \ -\ - while (L < R) \ - { \ - size_t M = L + (R - L) / 2; \ -\ - if (_list_->f_val->cmp(_list_->buffer[M], value) > 0) \ - R = M; \ - else \ - L = M + 1; \ - } \ -\ - if (L > 0 && _list_->f_val->cmp(_list_->buffer[L - 1], value) == 0) \ - return L - 1; \ -\ - /* Not found */ \ - return _list_->count; \ - } \ -\ - /* Characteristics of this quicksort implementation: */ \ - /* - Hybrid: uses insertion sort for small arrays */ \ - /* - Partition: Lomuto's Method */ \ - /* - Tail recursion: minimize recursion depth */ \ - void CMC_(PFX, _impl_sort_quicksort)(V * array, int (*cmp)(V, V), size_t low, size_t high) \ - { \ - while (low < high) \ - { \ - /* Quicksort performs poorly for smaller arrays so let */ \ - /* insertion sort do the job */ \ - if (high - low < 10) \ - { \ - CMC_(PFX, _impl_sort_insertion)(array, cmp, low, high); \ - break; \ - } \ - else \ - { \ - /* Partition */ \ - V pivot = array[high]; \ -\ - size_t pindex = low; \ -\ - for (size_t i = low; i < high; i++) \ - { \ - if (cmp(array[i], pivot) <= 0) \ - { \ - V _tmp_ = array[i]; \ - array[i] = array[pindex]; \ - array[pindex] = _tmp_; \ -\ - pindex++; \ - } \ - } \ -\ - V _tmp_ = array[pindex]; \ - array[pindex] = array[high]; \ - array[high] = _tmp_; \ -\ - /* Tail recursion */ \ - if (pindex - low < high - pindex) \ - { \ - CMC_(PFX, _impl_sort_quicksort) \ - (array, cmp, low, pindex - 1); \ -\ - low = pindex + 1; \ - } \ - else \ - { \ - CMC_(PFX, _impl_sort_quicksort) \ - (array, cmp, pindex + 1, high); \ -\ - high = pindex - 1; \ - } \ - } \ - } \ - } \ -\ - void CMC_(PFX, _impl_sort_insertion)(V * array, int (*cmp)(V, V), size_t low, size_t high) \ - { \ - for (size_t i = low + 1; i <= high; i++) \ - { \ - V _tmp_ = array[i]; \ - size_t j = i; \ -\ - while (j > low && cmp(array[j - 1], _tmp_) > 0) \ - { \ - array[j] = array[j - 1]; \ - j--; \ - } \ -\ - array[j] = _tmp_; \ - } \ - } - -#endif /* CMC_CMC_SORTEDLIST_H */ diff --git a/src/cmc_stack.h b/src/cmc_stack.h deleted file mode 100644 index d922da4..0000000 --- a/src/cmc_stack.h +++ /dev/null @@ -1,439 +0,0 @@ -/** - * Copyright (c) 2019 Leonardo Vencovsky - * - * This file is part of the C Macro Collections Libray. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * cmc_stack.h - * - * Creation Date: 14/02/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -/** - * Stack - * - * A Stack is a Last-in First-out (or First-in Last-out) data structure used in - * a variety of algorithms. It is a Dynamic Array that can only add or remove - * its elements at the end of the buffer, in this case, it represents the top of - * the stack. - * - * It has three main functions: `push` which adds an element at the top of the - * stack; `pop` which removes the top element from the stack; and `top` which - * returns the top element without removing it (it is also sometimes called - * `peek`). - * - * A Stack is used in algorithms like backtracking, depth-first search, - * expression evaluation, syntax parsing and many more. - */ - -#ifndef CMC_CMC_STACK_H -#define CMC_CMC_STACK_H - -/* ------------------------------------------------------------------------- - * Core functionalities of the C Macro Collections Library - * ------------------------------------------------------------------------- */ -#include "cor_core.h" - -/** - * Core Stack implementation - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_CMC_STACK_CORE(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_CMC_STACK_CORE_, ACCESS), CMC_(_, FILE))(PARAMS) - -/* PRIVATE or PUBLIC solver */ -#define CMC_CMC_STACK_CORE_PUBLIC_HEADER(PARAMS) \ - CMC_CMC_STACK_CORE_STRUCT(PARAMS) \ - CMC_CMC_STACK_CORE_HEADER(PARAMS) - -#define CMC_CMC_STACK_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_STACK_CORE_SOURCE(PARAMS) - -#define CMC_CMC_STACK_CORE_PRIVATE_HEADER(PARAMS) \ - struct CMC_PARAM_SNAME(PARAMS); \ - CMC_CMC_STACK_CORE_HEADER(PARAMS) - -#define CMC_CMC_STACK_CORE_PRIVATE_SOURCE(PARAMS) \ - CMC_CMC_STACK_CORE_STRUCT(PARAMS) \ - CMC_CMC_STACK_CORE_SOURCE(PARAMS) - -/* Lowest level API */ -#define CMC_CMC_STACK_CORE_STRUCT(PARAMS) \ - CMC_CMC_STACK_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_CMC_STACK_CORE_HEADER(PARAMS) \ - CMC_CMC_STACK_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_CMC_STACK_CORE_SOURCE(PARAMS) \ - CMC_CMC_STACK_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -/* ------------------------------------------------------------------------- - * Struct - * ------------------------------------------------------------------------- */ -#define CMC_CMC_STACK_CORE_STRUCT_(PFX, SNAME, V) \ -\ - /* Stack Structure */ \ - struct SNAME \ - { \ - /* Dynamic array of elements */ \ - V *buffer; \ -\ - /* Current array capacity */ \ - size_t capacity; \ -\ - /* Current amount of elements */ \ - size_t count; \ -\ - /* Flags indicating errors or success */ \ - int flag; \ -\ - /* Value function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ -\ - /* Custom allocation functions */ \ - struct CMC_ALLOC_NODE_NAME *alloc; \ -\ - /* Custom callback functions */ \ - CMC_CALLBACKS_DECL; \ - }; - -/* ------------------------------------------------------------------------- - * Header - * ------------------------------------------------------------------------- */ -#define CMC_CMC_STACK_CORE_HEADER_(PFX, SNAME, V) \ -\ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(V); \ -\ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(V); \ -\ - /* To string function */ \ - CMC_DEF_FTAB_STR(V); \ -\ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(V); \ -\ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(V); \ -\ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(V); \ - }; \ -\ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks); \ - void CMC_(PFX, _clear)(struct SNAME * _stack_); \ - void CMC_(PFX, _free)(struct SNAME * _stack_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _stack_, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _push)(struct SNAME * _stack_, V value); \ - bool CMC_(PFX, _pop)(struct SNAME * _stack_); \ - /* Element Access */ \ - V CMC_(PFX, _top)(struct SNAME * _stack_); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _stack_, V value); \ - bool CMC_(PFX, _empty)(struct SNAME * _stack_); \ - bool CMC_(PFX, _full)(struct SNAME * _stack_); \ - size_t CMC_(PFX, _count)(struct SNAME * _stack_); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _stack_); \ - int CMC_(PFX, _flag)(struct SNAME * _stack_); \ - /* Collection Utility */ \ - bool CMC_(PFX, _resize)(struct SNAME * _stack_, size_t capacity); \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _stack_); \ - bool CMC_(PFX, _equals)(struct SNAME * _stack1_, struct SNAME * _stack2_); - -/* ------------------------------------------------------------------------- - * Source - * ------------------------------------------------------------------------- */ -#define CMC_CMC_STACK_CORE_SOURCE_(PFX, SNAME, V) \ -\ - /* Implementation Detail Functions */ \ - /* None */ \ -\ - struct SNAME *CMC_(PFX, _new)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - return CMC_(PFX, _new_custom)(capacity, f_val, NULL, NULL); \ - } \ -\ - struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - if (capacity < 1) \ - return NULL; \ - if (!f_val) \ - return NULL; \ -\ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ -\ - struct SNAME *_stack_ = alloc->malloc(sizeof(struct SNAME)); \ -\ - if (!_stack_) \ - return NULL; \ -\ - _stack_->buffer = alloc->calloc(capacity, sizeof(V)); \ -\ - if (!_stack_->buffer) \ - { \ - alloc->free(_stack_); \ - return NULL; \ - } \ -\ - _stack_->capacity = capacity; \ - _stack_->count = 0; \ - _stack_->flag = CMC_FLAG_OK; \ - _stack_->f_val = f_val; \ - _stack_->alloc = alloc; \ - CMC_CALLBACKS_ASSIGN(_stack_, callbacks); \ -\ - return _stack_; \ - } \ -\ - void CMC_(PFX, _clear)(struct SNAME * _stack_) \ - { \ - if (_stack_->f_val->free) \ - { \ - for (size_t i = 0; i < _stack_->count; i++) \ - _stack_->f_val->free(_stack_->buffer[i]); \ - } \ -\ - memset(_stack_->buffer, 0, sizeof(V) * _stack_->capacity); \ -\ - _stack_->count = 0; \ - _stack_->flag = CMC_FLAG_OK; \ - } \ -\ - void CMC_(PFX, _free)(struct SNAME * _stack_) \ - { \ - if (_stack_->f_val->free) \ - { \ - for (size_t i = 0; i < _stack_->count; i++) \ - _stack_->f_val->free(_stack_->buffer[i]); \ - } \ -\ - _stack_->alloc->free(_stack_->buffer); \ - _stack_->alloc->free(_stack_); \ - } \ -\ - void CMC_(PFX, _customize)(struct SNAME * _stack_, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - if (!alloc) \ - _stack_->alloc = &cmc_alloc_node_default; \ - else \ - _stack_->alloc = alloc; \ -\ - CMC_CALLBACKS_ASSIGN(_stack_, callbacks); \ -\ - _stack_->flag = CMC_FLAG_OK; \ - } \ -\ - bool CMC_(PFX, _push)(struct SNAME * _stack_, V value) \ - { \ - if (CMC_(PFX, _full)(_stack_)) \ - { \ - if (!CMC_(PFX, _resize)(_stack_, _stack_->capacity * 2)) \ - return false; \ - } \ -\ - _stack_->buffer[_stack_->count++] = value; \ -\ - _stack_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_stack_, create); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _pop)(struct SNAME * _stack_) \ - { \ - if (CMC_(PFX, _empty)(_stack_)) \ - { \ - _stack_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - _stack_->buffer[--_stack_->count] = (V){ 0 }; \ -\ - _stack_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_stack_, delete); \ -\ - return true; \ - } \ -\ - V CMC_(PFX, _top)(struct SNAME * _stack_) \ - { \ - if (CMC_(PFX, _empty)(_stack_)) \ - { \ - _stack_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ -\ - _stack_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_stack_, read); \ -\ - return _stack_->buffer[_stack_->count - 1]; \ - } \ -\ - bool CMC_(PFX, _contains)(struct SNAME * _stack_, V value) \ - { \ - _stack_->flag = CMC_FLAG_OK; \ -\ - bool result = false; \ -\ - for (size_t i = 0; i < _stack_->count; i++) \ - { \ - if (_stack_->f_val->cmp(_stack_->buffer[i], value) == 0) \ - { \ - result = true; \ - break; \ - } \ - } \ -\ - CMC_CALLBACKS_CALL(_stack_, read); \ -\ - return result; \ - } \ -\ - bool CMC_(PFX, _empty)(struct SNAME * _stack_) \ - { \ - return _stack_->count == 0; \ - } \ -\ - bool CMC_(PFX, _full)(struct SNAME * _stack_) \ - { \ - return _stack_->count >= _stack_->capacity; \ - } \ -\ - size_t CMC_(PFX, _count)(struct SNAME * _stack_) \ - { \ - return _stack_->count; \ - } \ -\ - size_t CMC_(PFX, _capacity)(struct SNAME * _stack_) \ - { \ - return _stack_->capacity; \ - } \ -\ - int CMC_(PFX, _flag)(struct SNAME * _stack_) \ - { \ - return _stack_->flag; \ - } \ -\ - bool CMC_(PFX, _resize)(struct SNAME * _stack_, size_t capacity) \ - { \ - if (_stack_->capacity == capacity) \ - goto success; \ -\ - if (capacity < _stack_->count) \ - { \ - _stack_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ -\ - V *new_buffer = _stack_->alloc->realloc(_stack_->buffer, sizeof(V) * capacity); \ -\ - if (!new_buffer) \ - { \ - _stack_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ -\ - /* TODO zero out new slots */ \ -\ - _stack_->buffer = new_buffer; \ - _stack_->capacity = capacity; \ -\ - success: \ -\ - _stack_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_stack_, resize); \ -\ - return true; \ - } \ -\ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _stack_) \ - { \ - struct SNAME *result = CMC_(PFX, _new_custom)(_stack_->capacity, _stack_->f_val, _stack_->alloc, NULL); \ -\ - if (!result) \ - { \ - _stack_->flag = CMC_FLAG_ERROR; \ - return NULL; \ - } \ -\ - CMC_CALLBACKS_ASSIGN(result, _stack_->callbacks); \ -\ - if (_stack_->f_val->cpy) \ - { \ - for (size_t i = 0; i < _stack_->count; i++) \ - result->buffer[i] = _stack_->f_val->cpy(_stack_->buffer[i]); \ - } \ - else \ - memcpy(result->buffer, _stack_->buffer, sizeof(V) * _stack_->count); \ -\ - result->count = _stack_->count; \ -\ - _stack_->flag = CMC_FLAG_OK; \ -\ - return result; \ - } \ -\ - bool CMC_(PFX, _equals)(struct SNAME * _stack1_, struct SNAME * _stack2_) \ - { \ - _stack1_->flag = CMC_FLAG_OK; \ - _stack2_->flag = CMC_FLAG_OK; \ -\ - if (_stack1_->count != _stack2_->count) \ - return false; \ -\ - for (size_t i = 0; i < _stack1_->count; i++) \ - { \ - if (_stack1_->f_val->cmp(_stack1_->buffer[i], _stack2_->buffer[i]) != 0) \ - return false; \ - } \ -\ - return true; \ - } - -#endif /* CMC_CMC_STACK_H */ diff --git a/src/cmc_treemap.h b/src/cmc_treemap.h deleted file mode 100644 index 78ef338..0000000 --- a/src/cmc_treemap.h +++ /dev/null @@ -1,978 +0,0 @@ -/** - * Copyright (c) 2019 Leonardo Vencovsky - * - * This file is part of the C Macro Collections Libray. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * cmc_treemap.h - * - * Creation Date: 28/03/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -/** - * TreeMap - * - * A TreeMap is an implementation of a Map that keeps its keys sorted. Like a - * Map, it has only unique keys. This implementation uses a balanced binary - * tree called AVL Tree that uses the height of nodes to keep its keys balanced. - */ - -#ifndef CMC_CMC_TREEMAP_H -#define CMC_CMC_TREEMAP_H - -/* ------------------------------------------------------------------------- - * Core functionalities of the C Macro Collections Library - * ------------------------------------------------------------------------- */ -#include "cor_core.h" - -/** - * Core TreeMap implementation - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_CMC_TREEMAP_CORE(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_CMC_TREEMAP_CORE_, ACCESS), CMC_(_, FILE))(PARAMS) - -/* PRIVATE or PUBLIC solver */ -#define CMC_CMC_TREEMAP_CORE_PUBLIC_HEADER(PARAMS) \ - CMC_CMC_TREEMAP_CORE_STRUCT(PARAMS) \ - CMC_CMC_TREEMAP_CORE_HEADER(PARAMS) - -#define CMC_CMC_TREEMAP_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_TREEMAP_CORE_SOURCE(PARAMS) - -#define CMC_CMC_TREEMAP_CORE_PRIVATE_HEADER(PARAMS) \ - struct CMC_PARAM_SNAME(PARAMS); \ - struct CMC_DEF_NODE(CMC_PARAM_SNAME(PARAMS)); \ - CMC_CMC_TREEMAP_CORE_HEADER(PARAMS) - -#define CMC_CMC_TREEMAP_CORE_PRIVATE_SOURCE(PARAMS) \ - CMC_CMC_TREEMAP_CORE_STRUCT(PARAMS) \ - CMC_CMC_TREEMAP_CORE_SOURCE(PARAMS) - -/* Lowest level API */ -#define CMC_CMC_TREEMAP_CORE_STRUCT(PARAMS) \ - CMC_CMC_TREEMAP_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_CMC_TREEMAP_CORE_HEADER(PARAMS) \ - CMC_CMC_TREEMAP_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_CMC_TREEMAP_CORE_SOURCE(PARAMS) \ - CMC_CMC_TREEMAP_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -/* ------------------------------------------------------------------------- - * Struct - * ------------------------------------------------------------------------- */ -#define CMC_CMC_TREEMAP_CORE_STRUCT_(PFX, SNAME, K, V) \ -\ - /* Treemap Structure */ \ - struct SNAME \ - { \ - /* Root node */ \ - struct CMC_DEF_NODE(SNAME) * root; \ -\ - /* Current amount of keys */ \ - size_t count; \ -\ - /* Flags indicating errors or success */ \ - int flag; \ -\ - /* Key function table */ \ - struct CMC_DEF_FKEY(SNAME) * f_key; \ -\ - /* Value function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ -\ - /* Custom allocation functions */ \ - struct CMC_ALLOC_NODE_NAME *alloc; \ -\ - /* Custom callback functions */ \ - CMC_CALLBACKS_DECL; \ - }; \ -\ - /* Treemap Node */ \ - struct CMC_DEF_NODE(SNAME) \ - { \ - /* Node Key */ \ - K key; \ -\ - /* Node Value */ \ - V value; \ -\ - /* Node height used by the AVL tree to keep it strictly balanced */ \ - unsigned char height; \ -\ - /* Right child node or subtree */ \ - struct CMC_DEF_NODE(SNAME) * right; \ -\ - /* Left child node or subtree */ \ - struct CMC_DEF_NODE(SNAME) * left; \ -\ - /* Parent node */ \ - struct CMC_DEF_NODE(SNAME) * parent; \ - }; - -/* ------------------------------------------------------------------------- - * Header - * ------------------------------------------------------------------------- */ -#define CMC_CMC_TREEMAP_CORE_HEADER_(PFX, SNAME, K, V) \ -\ - /* Key struct function table */ \ - struct CMC_DEF_FKEY(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(K); \ -\ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(K); \ -\ - /* To string function */ \ - CMC_DEF_FTAB_STR(K); \ -\ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(K); \ -\ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(K); \ -\ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(K); \ - }; \ -\ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(V); \ -\ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(V); \ -\ - /* To string function */ \ - CMC_DEF_FTAB_STR(V); \ -\ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(V); \ -\ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(V); \ -\ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(V); \ - }; \ -\ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(struct CMC_DEF_FKEY(SNAME) * f_key, struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FKEY(SNAME) * f_key, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks); \ - void CMC_(PFX, _clear)(struct SNAME * _map_); \ - void CMC_(PFX, _free)(struct SNAME * _map_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _map_, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value); \ - bool CMC_(PFX, _update)(struct SNAME * _map_, K key, V new_value, V * old_value); \ - bool CMC_(PFX, _remove)(struct SNAME * _map_, K key, V * out_value); \ - /* Element Access */ \ - bool CMC_(PFX, _max)(struct SNAME * _map_, K * key, V * value); \ - bool CMC_(PFX, _min)(struct SNAME * _map_, K * key, V * value); \ - V CMC_(PFX, _get)(struct SNAME * _map_, K key); \ - V *CMC_(PFX, _get_ref)(struct SNAME * _map_, K key); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _map_, K key); \ - bool CMC_(PFX, _empty)(struct SNAME * _map_); \ - size_t CMC_(PFX, _count)(struct SNAME * _map_); \ - int CMC_(PFX, _flag)(struct SNAME * _map_); \ - /* Collection Utility */ \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_); \ - bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_); - -/* ------------------------------------------------------------------------- - * Source - * ------------------------------------------------------------------------- */ -#define CMC_CMC_TREEMAP_CORE_SOURCE_(PFX, SNAME, K, V) \ -\ - /* Implementation Detail Functions */ \ - static struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _impl_new_node)(struct SNAME * _map_, K key, V value); \ - static struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _impl_get_node)(struct SNAME * _map_, K key); \ - static unsigned char CMC_(PFX, _impl_h)(struct CMC_DEF_NODE(SNAME) * node); \ - static unsigned char CMC_(PFX, _impl_hupdate)(struct CMC_DEF_NODE(SNAME) * node); \ - static void CMC_(PFX, _impl_rotate_right)(struct CMC_DEF_NODE(SNAME) * *Z); \ - static void CMC_(PFX, _impl_rotate_left)(struct CMC_DEF_NODE(SNAME) * *Z); \ - static void CMC_(PFX, _impl_rebalance)(struct SNAME * _map_, struct CMC_DEF_NODE(SNAME) * node); \ -\ - struct SNAME *CMC_(PFX, _new)(struct CMC_DEF_FKEY(SNAME) * f_key, struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - return CMC_(PFX, _new_custom)(f_key, f_val, NULL, NULL); \ - } \ -\ - struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FKEY(SNAME) * f_key, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - if (!f_key || !f_val) \ - return NULL; \ -\ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ -\ - struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \ -\ - if (!_map_) \ - return NULL; \ -\ - _map_->count = 0; \ - _map_->root = NULL; \ - _map_->flag = CMC_FLAG_OK; \ - _map_->f_key = f_key; \ - _map_->f_val = f_val; \ - _map_->alloc = alloc; \ - CMC_CALLBACKS_ASSIGN(_map_, callbacks); \ -\ - return _map_; \ - } \ -\ - void CMC_(PFX, _clear)(struct SNAME * _map_) \ - { \ - struct CMC_DEF_NODE(SNAME) *scan = _map_->root; \ - struct CMC_DEF_NODE(SNAME) *up = NULL; \ -\ - while (scan != NULL) \ - { \ - if (scan->left != NULL) \ - { \ - struct CMC_DEF_NODE(SNAME) *left = scan->left; \ -\ - scan->left = up; \ - up = scan; \ - scan = left; \ - } \ - else if (scan->right != NULL) \ - { \ - struct CMC_DEF_NODE(SNAME) *right = scan->right; \ -\ - scan->left = up; \ - scan->right = NULL; \ - up = scan; \ - scan = right; \ - } \ - else \ - { \ - if (up == NULL) \ - { \ - if (_map_->f_key->free) \ - _map_->f_key->free(scan->key); \ - if (_map_->f_val->free) \ - _map_->f_val->free(scan->value); \ -\ - _map_->alloc->free(scan); \ - scan = NULL; \ - } \ -\ - while (up != NULL) \ - { \ - if (_map_->f_key->free) \ - _map_->f_key->free(scan->key); \ - if (_map_->f_val->free) \ - _map_->f_val->free(scan->value); \ -\ - _map_->alloc->free(scan); \ -\ - if (up->right != NULL) \ - { \ - scan = up->right; \ - up->right = NULL; \ - break; \ - } \ - else \ - { \ - scan = up; \ - up = up->left; \ - } \ - } \ - } \ - } \ -\ - _map_->count = 0; \ - _map_->root = NULL; \ - _map_->flag = CMC_FLAG_OK; \ - } \ -\ - void CMC_(PFX, _free)(struct SNAME * _map_) \ - { \ - CMC_(PFX, _clear)(_map_); \ -\ - _map_->alloc->free(_map_); \ - } \ -\ - void CMC_(PFX, _customize)(struct SNAME * _map_, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - if (!alloc) \ - _map_->alloc = &cmc_alloc_node_default; \ - else \ - _map_->alloc = alloc; \ -\ - CMC_CALLBACKS_ASSIGN(_map_, callbacks); \ -\ - _map_->flag = CMC_FLAG_OK; \ - } \ -\ - bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->root = CMC_(PFX, _impl_new_node)(_map_, key, value); \ -\ - if (!_map_->root) \ - { \ - _map_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ - } \ - else \ - { \ - struct CMC_DEF_NODE(SNAME) *scan = _map_->root; \ - struct CMC_DEF_NODE(SNAME) *parent = scan; \ -\ - while (scan != NULL) \ - { \ - parent = scan; \ -\ - if (_map_->f_key->cmp(scan->key, key) > 0) \ - scan = scan->left; \ - else if (_map_->f_key->cmp(scan->key, key) < 0) \ - scan = scan->right; \ - else \ - { \ - _map_->flag = CMC_FLAG_DUPLICATE; \ - return false; \ - } \ - } \ -\ - struct CMC_DEF_NODE(SNAME) * node; \ -\ - if (_map_->f_key->cmp(parent->key, key) > 0) \ - { \ - parent->left = CMC_(PFX, _impl_new_node)(_map_, key, value); \ -\ - if (!parent->left) \ - { \ - _map_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ -\ - parent->left->parent = parent; \ - node = parent->left; \ - } \ - else \ - { \ - parent->right = CMC_(PFX, _impl_new_node)(_map_, key, value); \ -\ - if (!parent->right) \ - { \ - _map_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ -\ - parent->right->parent = parent; \ - node = parent->right; \ - } \ -\ - CMC_(PFX, _impl_rebalance)(_map_, node); \ - } \ -\ - _map_->count++; \ - _map_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_map_, create); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _update)(struct SNAME * _map_, K key, V new_value, V * old_value) \ - { \ - struct CMC_DEF_NODE(SNAME) *node = CMC_(PFX, _impl_get_node)(_map_, key); \ -\ - if (!node) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return false; \ - } \ -\ - if (old_value) \ - *old_value = node->value; \ -\ - node->value = new_value; \ -\ - _map_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_map_, update); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _remove)(struct SNAME * _map_, K key, V * out_value) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - struct CMC_DEF_NODE(SNAME) *node = CMC_(PFX, _impl_get_node)(_map_, key); \ -\ - if (!node) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return false; \ - } \ -\ - if (out_value) \ - *out_value = node->value; \ -\ - struct CMC_DEF_NODE(SNAME) *temp = NULL, *unbalanced = NULL; \ -\ - bool is_root = node->parent == NULL; \ -\ - if (node->left == NULL && node->right == NULL) \ - { \ - if (is_root) \ - _map_->root = NULL; \ - else \ - { \ - unbalanced = node->parent; \ -\ - if (node->parent->right == node) \ - node->parent->right = NULL; \ - else \ - node->parent->left = NULL; \ - } \ -\ - _map_->alloc->free(node); \ - } \ - else if (node->left == NULL) \ - { \ - if (is_root) \ - { \ - _map_->root = node->right; \ - _map_->root->parent = NULL; \ - } \ - else \ - { \ - unbalanced = node->parent; \ -\ - node->right->parent = node->parent; \ -\ - if (node->parent->right == node) \ - node->parent->right = node->right; \ - else \ - node->parent->left = node->right; \ - } \ -\ - _map_->alloc->free(node); \ - } \ - else if (node->right == NULL) \ - { \ - if (is_root) \ - { \ - _map_->root = node->left; \ - _map_->root->parent = NULL; \ - } \ - else \ - { \ - unbalanced = node->parent; \ -\ - node->left->parent = node->parent; \ -\ - if (node->parent->right == node) \ - node->parent->right = node->left; \ - else \ - node->parent->left = node->left; \ - } \ -\ - _map_->alloc->free(node); \ - } \ - else \ - { \ - temp = node->right; \ - while (temp->left != NULL) \ - temp = temp->left; \ -\ - K temp_key = temp->key; \ - V temp_val = temp->value; \ -\ - unbalanced = temp->parent; \ -\ - if (temp->left == NULL && temp->right == NULL) \ - { \ - if (temp->parent->right == temp) \ - temp->parent->right = NULL; \ - else \ - temp->parent->left = NULL; \ - } \ - else if (temp->left == NULL) \ - { \ - temp->right->parent = temp->parent; \ -\ - if (temp->parent->right == temp) \ - temp->parent->right = temp->right; \ - else \ - temp->parent->left = temp->right; \ - } \ - else if (temp->right == NULL) \ - { \ - temp->left->parent = temp->parent; \ -\ - if (temp->parent->right == temp) \ - temp->parent->right = temp->left; \ - else \ - temp->parent->left = temp->left; \ - } \ -\ - _map_->alloc->free(temp); \ -\ - node->key = temp_key; \ - node->value = temp_val; \ - } \ -\ - if (unbalanced != NULL) \ - CMC_(PFX, _impl_rebalance)(_map_, unbalanced); \ -\ - if (_map_->count == 0) \ - _map_->root = NULL; \ -\ - _map_->count--; \ - _map_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_map_, delete); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _max)(struct SNAME * _map_, K * key, V * value) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - struct CMC_DEF_NODE(SNAME) *scan = _map_->root; \ -\ - while (scan->right != NULL) \ - scan = scan->right; \ -\ - if (key) \ - *key = scan->key; \ - if (value) \ - *value = scan->value; \ -\ - _map_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_map_, read); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _min)(struct SNAME * _map_, K * key, V * value) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - struct CMC_DEF_NODE(SNAME) *scan = _map_->root; \ -\ - while (scan->left != NULL) \ - scan = scan->left; \ -\ - if (key) \ - *key = scan->key; \ - if (value) \ - *value = scan->value; \ -\ - _map_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_map_, read); \ -\ - return true; \ - } \ -\ - V CMC_(PFX, _get)(struct SNAME * _map_, K key) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ -\ - struct CMC_DEF_NODE(SNAME) *node = CMC_(PFX, _impl_get_node)(_map_, key); \ -\ - if (!node) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return (V){ 0 }; \ - } \ -\ - _map_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_map_, read); \ -\ - return node->value; \ - } \ -\ - V *CMC_(PFX, _get_ref)(struct SNAME * _map_, K key) \ - { \ - if (CMC_(PFX, _empty)(_map_)) \ - { \ - _map_->flag = CMC_FLAG_EMPTY; \ - return NULL; \ - } \ -\ - struct CMC_DEF_NODE(SNAME) *node = CMC_(PFX, _impl_get_node)(_map_, key); \ -\ - if (!node) \ - { \ - _map_->flag = CMC_FLAG_NOT_FOUND; \ - return NULL; \ - } \ -\ - _map_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_map_, read); \ -\ - return &(node->value); \ - } \ -\ - bool CMC_(PFX, _contains)(struct SNAME * _map_, K key) \ - { \ - bool result = CMC_(PFX, _impl_get_node)(_map_, key) != NULL; \ -\ - CMC_CALLBACKS_CALL(_map_, read); \ -\ - return result; \ - } \ -\ - bool CMC_(PFX, _empty)(struct SNAME * _map_) \ - { \ - return _map_->count == 0; \ - } \ -\ - size_t CMC_(PFX, _count)(struct SNAME * _map_) \ - { \ - return _map_->count; \ - } \ -\ - int CMC_(PFX, _flag)(struct SNAME * _map_) \ - { \ - return _map_->flag; \ - } \ -\ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_) \ - { \ - /* Callback will be added later */ \ - struct SNAME *result = CMC_(PFX, _new_custom)(_map_->f_key, _map_->f_val, _map_->alloc, NULL); \ -\ - if (!result) \ - { \ - _map_->flag = CMC_FLAG_ERROR; \ - return NULL; \ - } \ -\ - struct CMC_DEF_NODE(SNAME) *root = _map_->root; \ -\ - bool left_done = false; \ -\ - while (root) \ - { \ - if (!left_done) \ - { \ - while (root->left) \ - root = root->left; \ - } \ -\ - K key; \ - V value; \ -\ - if (_map_->f_key->cpy) \ - key = _map_->f_key->cpy(root->key); \ - else \ - key = root->key; \ - if (_map_->f_val->cpy) \ - value = _map_->f_val->cpy(root->value); \ - else \ - value = root->value; \ -\ - /* TODO check this for errors */ \ - CMC_(PFX, _insert)(result, key, value); \ -\ - left_done = true; \ -\ - if (root->right) \ - { \ - left_done = false; \ - root = root->right; \ - } \ - else if (root->parent) \ - { \ - while (root->parent && root == root->parent->right) \ - root = root->parent; \ -\ - if (!root->parent) \ - break; \ -\ - root = root->parent; \ - } \ - else \ - break; \ - } \ -\ - _map_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_ASSIGN(result, _map_->callbacks); \ -\ - return result; \ - } \ -\ - bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_) \ - { \ - _map1_->flag = CMC_FLAG_OK; \ - _map2_->flag = CMC_FLAG_OK; \ -\ - if (_map1_->count != _map2_->count) \ - return false; \ -\ - struct CMC_DEF_NODE(SNAME) *root = _map1_->root; \ -\ - bool left_done = false; \ -\ - while (root) \ - { \ - if (!left_done) \ - { \ - while (root->left) \ - root = root->left; \ - } \ -\ - /* TODO this can be optimized by doing two in-order traversals */ \ - struct CMC_DEF_NODE(SNAME) *node = CMC_(PFX, _impl_get_node)(_map2_, root->key); \ -\ - if (node == NULL) \ - return false; \ -\ - if (_map1_->f_val->cmp(node->value, root->value) != 0) \ - return false; \ -\ - left_done = true; \ -\ - if (root->right) \ - { \ - left_done = false; \ - root = root->right; \ - } \ - else if (root->parent) \ - { \ - while (root->parent && root == root->parent->right) \ - root = root->parent; \ -\ - if (!root->parent) \ - break; \ -\ - root = root->parent; \ - } \ - else \ - break; \ - } \ -\ - return true; \ - } \ -\ - static struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _impl_new_node)(struct SNAME * _map_, K key, V value) \ - { \ - struct CMC_DEF_NODE(SNAME) *node = _map_->alloc->malloc(sizeof(struct CMC_DEF_NODE(SNAME))); \ -\ - if (!node) \ - return NULL; \ -\ - node->key = key; \ - node->value = value; \ - node->right = NULL; \ - node->left = NULL; \ - node->parent = NULL; \ - node->height = 0; \ -\ - return node; \ - } \ -\ - static struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _impl_get_node)(struct SNAME * _map_, K key) \ - { \ - struct CMC_DEF_NODE(SNAME) *scan = _map_->root; \ -\ - while (scan != NULL) \ - { \ - if (_map_->f_key->cmp(scan->key, key) > 0) \ - scan = scan->left; \ - else if (_map_->f_key->cmp(scan->key, key) < 0) \ - scan = scan->right; \ - else \ - return scan; \ - } \ -\ - return NULL; \ - } \ -\ - static unsigned char CMC_(PFX, _impl_h)(struct CMC_DEF_NODE(SNAME) * node) \ - { \ - if (node == NULL) \ - return 0; \ -\ - return node->height; \ - } \ -\ - static unsigned char CMC_(PFX, _impl_hupdate)(struct CMC_DEF_NODE(SNAME) * node) \ - { \ - if (node == NULL) \ - return 0; \ -\ - unsigned char h_l = CMC_(PFX, _impl_h)(node->left); \ - unsigned char h_r = CMC_(PFX, _impl_h)(node->right); \ -\ - return 1 + (h_l > h_r ? h_l : h_r); \ - } \ -\ - static void CMC_(PFX, _impl_rotate_right)(struct CMC_DEF_NODE(SNAME) * *Z) \ - { \ - struct CMC_DEF_NODE(SNAME) *root = *Z; \ - struct CMC_DEF_NODE(SNAME) *new_root = root->left; \ -\ - if (root->parent != NULL) \ - { \ - if (root->parent->left == root) \ - root->parent->left = new_root; \ - else \ - root->parent->right = new_root; \ - } \ -\ - new_root->parent = root->parent; \ -\ - root->parent = new_root; \ - root->left = new_root->right; \ -\ - if (root->left) \ - root->left->parent = root; \ -\ - new_root->right = root; \ -\ - root->height = CMC_(PFX, _impl_hupdate)(root); \ - new_root->height = CMC_(PFX, _impl_hupdate)(new_root); \ -\ - *Z = new_root; \ - } \ -\ - static void CMC_(PFX, _impl_rotate_left)(struct CMC_DEF_NODE(SNAME) * *Z) \ - { \ - struct CMC_DEF_NODE(SNAME) *root = *Z; \ - struct CMC_DEF_NODE(SNAME) *new_root = root->right; \ -\ - if (root->parent != NULL) \ - { \ - if (root->parent->right == root) \ - root->parent->right = new_root; \ - else \ - root->parent->left = new_root; \ - } \ -\ - new_root->parent = root->parent; \ -\ - root->parent = new_root; \ - root->right = new_root->left; \ -\ - if (root->right) \ - root->right->parent = root; \ -\ - new_root->left = root; \ -\ - root->height = CMC_(PFX, _impl_hupdate)(root); \ - new_root->height = CMC_(PFX, _impl_hupdate)(new_root); \ -\ - *Z = new_root; \ - } \ -\ - static void CMC_(PFX, _impl_rebalance)(struct SNAME * _map_, struct CMC_DEF_NODE(SNAME) * node) \ - { \ - struct CMC_DEF_NODE(SNAME) *scan = node, *child = NULL; \ -\ - int balance; \ - bool is_root = false; \ -\ - while (scan != NULL) \ - { \ - if (scan->parent == NULL) \ - is_root = true; \ -\ - scan->height = CMC_(PFX, _impl_hupdate)(scan); \ - balance = CMC_(PFX, _impl_h)(scan->right) - CMC_(PFX, _impl_h)(scan->left); \ -\ - if (balance >= 2) \ - { \ - child = scan->right; \ -\ - if (CMC_(PFX, _impl_h)(child->right) < CMC_(PFX, _impl_h)(child->left)) \ - CMC_(PFX, _impl_rotate_right)(&(scan->right)); \ -\ - CMC_(PFX, _impl_rotate_left)(&scan); \ - } \ - else if (balance <= -2) \ - { \ - child = scan->left; \ -\ - if (CMC_(PFX, _impl_h)(child->left) < CMC_(PFX, _impl_h)(child->right)) \ - CMC_(PFX, _impl_rotate_left)(&(scan->left)); \ -\ - CMC_(PFX, _impl_rotate_right)(&scan); \ - } \ -\ - if (is_root) \ - { \ - _map_->root = scan; \ - is_root = false; \ - } \ -\ - scan = scan->parent; \ - } \ - } - -#endif /* CMC_CMC_TREEMAP_H */ diff --git a/src/cmc_treeset.h b/src/cmc_treeset.h deleted file mode 100644 index 2822016..0000000 --- a/src/cmc_treeset.h +++ /dev/null @@ -1,790 +0,0 @@ -/** - * Copyright (c) 2019 Leonardo Vencovsky - * - * This file is part of the C Macro Collections Libray. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * cmc_treeset.h - * - * Creation Date: 27/03/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -/** - * TreeSet - * - * A TreeSet is an implementation of a Set that keeps its elements sorted. Like - * a Set it has only unique keys. This implementation uses a balanced binary - * tree called AVL Tree that uses the height of nodes to keep its keys balanced. - */ - -#ifndef CMC_CMC_TREESET_H -#define CMC_CMC_TREESET_H - -/* ------------------------------------------------------------------------- - * Core functionalities of the C Macro Collections Library - * ------------------------------------------------------------------------- */ -#include "cor_core.h" - -/** - * Core TreeSet implementation - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_CMC_TREESET_CORE(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_CMC_TREESET_CORE_, ACCESS), CMC_(_, FILE))(PARAMS) - -/* PRIVATE or PUBLIC solver */ -#define CMC_CMC_TREESET_CORE_PUBLIC_HEADER(PARAMS) \ - CMC_CMC_TREESET_CORE_STRUCT(PARAMS) \ - CMC_CMC_TREESET_CORE_HEADER(PARAMS) - -#define CMC_CMC_TREESET_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_TREESET_CORE_SOURCE(PARAMS) - -#define CMC_CMC_TREESET_CORE_PRIVATE_HEADER(PARAMS) \ - struct CMC_PARAM_SNAME(PARAMS); \ - CMC_CMC_TREESET_CORE_HEADER(PARAMS) - -#define CMC_CMC_TREESET_CORE_PRIVATE_SOURCE(PARAMS) \ - CMC_CMC_TREESET_CORE_STRUCT(PARAMS) \ - CMC_CMC_TREESET_CORE_SOURCE(PARAMS) - -/* Lowest level API */ -#define CMC_CMC_TREESET_CORE_STRUCT(PARAMS) \ - CMC_CMC_TREESET_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_CMC_TREESET_CORE_HEADER(PARAMS) \ - CMC_CMC_TREESET_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_CMC_TREESET_CORE_SOURCE(PARAMS) \ - CMC_CMC_TREESET_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -/* ------------------------------------------------------------------------- - * Struct - * ------------------------------------------------------------------------- */ -#define CMC_CMC_TREESET_CORE_STRUCT_(PFX, SNAME, V) \ -\ - /* Treeset Structure */ \ - struct SNAME \ - { \ - /* Root node */ \ - struct CMC_DEF_NODE(SNAME) * root; \ -\ - /* Current amount of elements */ \ - size_t count; \ -\ - /* Flags indicating errors or success */ \ - int flag; \ -\ - /* Value function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ -\ - /* Custom allocation functions */ \ - struct CMC_ALLOC_NODE_NAME *alloc; \ -\ - /* Custom callback functions */ \ - CMC_CALLBACKS_DECL; \ - }; \ -\ - /* Treeset Node */ \ - struct CMC_DEF_NODE(SNAME) \ - { \ - /* Node element */ \ - V value; \ -\ - /* Node height used by the AVL tree to keep it strictly balanced */ \ - unsigned char height; \ -\ - /* Right child node or subtree */ \ - struct CMC_DEF_NODE(SNAME) * right; \ -\ - /* Left child node or subtree */ \ - struct CMC_DEF_NODE(SNAME) * left; \ -\ - /* Parent node */ \ - struct CMC_DEF_NODE(SNAME) * parent; \ - }; - -/* ------------------------------------------------------------------------- - * Header - * ------------------------------------------------------------------------- */ -#define CMC_CMC_TREESET_CORE_HEADER_(PFX, SNAME, V) \ -\ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(V); \ -\ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(V); \ -\ - /* To string function */ \ - CMC_DEF_FTAB_STR(V); \ -\ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(V); \ -\ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(V); \ -\ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(V); \ - }; \ -\ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME *CMC_(PFX, _new)(struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks); \ - void CMC_(PFX, _clear)(struct SNAME * _set_); \ - void CMC_(PFX, _free)(struct SNAME * _set_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _set_, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _insert)(struct SNAME * _set_, V value); \ - bool CMC_(PFX, _remove)(struct SNAME * _set_, V value); \ - /* Element Access */ \ - bool CMC_(PFX, _max)(struct SNAME * _set_, V * value); \ - bool CMC_(PFX, _min)(struct SNAME * _set_, V * value); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _set_, V value); \ - bool CMC_(PFX, _empty)(struct SNAME * _set_); \ - size_t CMC_(PFX, _count)(struct SNAME * _set_); \ - int CMC_(PFX, _flag)(struct SNAME * _set_); \ - /* Collection Utility */ \ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_); \ - bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_); - -/* ------------------------------------------------------------------------- - * Source - * ------------------------------------------------------------------------- */ -#define CMC_CMC_TREESET_CORE_SOURCE_(PFX, SNAME, V) \ -\ - /* Implementation Detail Functions */ \ - static struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _impl_new_node)(struct SNAME * _set_, V value); \ - static struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _impl_get_node)(struct SNAME * _set_, V value); \ - static unsigned char CMC_(PFX, _impl_h)(struct CMC_DEF_NODE(SNAME) * node); \ - static unsigned char CMC_(PFX, _impl_hupdate)(struct CMC_DEF_NODE(SNAME) * node); \ - static void CMC_(PFX, _impl_rotate_right)(struct CMC_DEF_NODE(SNAME) * *Z); \ - static void CMC_(PFX, _impl_rotate_left)(struct CMC_DEF_NODE(SNAME) * *Z); \ - static void CMC_(PFX, _impl_rebalance)(struct SNAME * _set_, struct CMC_DEF_NODE(SNAME) * node); \ -\ - struct SNAME *CMC_(PFX, _new)(struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - return CMC_(PFX, _new_custom)(f_val, NULL, NULL); \ - } \ -\ - struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - if (!f_val) \ - return NULL; \ -\ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ -\ - struct SNAME *_set_ = alloc->malloc(sizeof(struct SNAME)); \ -\ - if (!_set_) \ - return NULL; \ -\ - _set_->count = 0; \ - _set_->root = NULL; \ - _set_->flag = CMC_FLAG_OK; \ - _set_->f_val = f_val; \ - _set_->alloc = alloc; \ - CMC_CALLBACKS_ASSIGN(_set_, callbacks); \ -\ - return _set_; \ - } \ -\ - void CMC_(PFX, _clear)(struct SNAME * _set_) \ - { \ - struct CMC_DEF_NODE(SNAME) *scan = _set_->root; \ - struct CMC_DEF_NODE(SNAME) *up = NULL; \ -\ - while (scan != NULL) \ - { \ - if (scan->left != NULL) \ - { \ - struct CMC_DEF_NODE(SNAME) *left = scan->left; \ -\ - scan->left = up; \ - up = scan; \ - scan = left; \ - } \ - else if (scan->right != NULL) \ - { \ - struct CMC_DEF_NODE(SNAME) *right = scan->right; \ -\ - scan->left = up; \ - scan->right = NULL; \ - up = scan; \ - scan = right; \ - } \ - else \ - { \ - if (up == NULL) \ - { \ - if (_set_->f_val->free) \ - _set_->f_val->free(scan->value); \ -\ - _set_->alloc->free(scan); \ - scan = NULL; \ - } \ -\ - while (up != NULL) \ - { \ - if (_set_->f_val->free) \ - _set_->f_val->free(scan->value); \ -\ - _set_->alloc->free(scan); \ -\ - if (up->right != NULL) \ - { \ - scan = up->right; \ - up->right = NULL; \ - break; \ - } \ - else \ - { \ - scan = up; \ - up = up->left; \ - } \ - } \ - } \ - } \ -\ - _set_->count = 0; \ - _set_->root = NULL; \ - _set_->flag = CMC_FLAG_OK; \ - } \ -\ - void CMC_(PFX, _free)(struct SNAME * _set_) \ - { \ - CMC_(PFX, _clear)(_set_); \ -\ - _set_->alloc->free(_set_); \ - } \ -\ - void CMC_(PFX, _customize)(struct SNAME * _set_, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - if (!alloc) \ - _set_->alloc = &cmc_alloc_node_default; \ - else \ - _set_->alloc = alloc; \ -\ - CMC_CALLBACKS_ASSIGN(_set_, callbacks); \ -\ - _set_->flag = CMC_FLAG_OK; \ - } \ -\ - bool CMC_(PFX, _insert)(struct SNAME * _set_, V value) \ - { \ - if (CMC_(PFX, _empty)(_set_)) \ - { \ - _set_->root = CMC_(PFX, _impl_new_node)(_set_, value); \ -\ - if (!_set_->root) \ - { \ - _set_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ - } \ - else \ - { \ - struct CMC_DEF_NODE(SNAME) *scan = _set_->root; \ - struct CMC_DEF_NODE(SNAME) *parent = scan; \ -\ - while (scan != NULL) \ - { \ - parent = scan; \ -\ - if (_set_->f_val->cmp(scan->value, value) > 0) \ - scan = scan->left; \ - else if (_set_->f_val->cmp(scan->value, value) < 0) \ - scan = scan->right; \ - else \ - { \ - _set_->flag = CMC_FLAG_DUPLICATE; \ - return false; \ - } \ - } \ -\ - struct CMC_DEF_NODE(SNAME) * node; \ -\ - if (_set_->f_val->cmp(parent->value, value) > 0) \ - { \ - parent->left = CMC_(PFX, _impl_new_node)(_set_, value); \ -\ - if (!parent->left) \ - { \ - _set_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ -\ - parent->left->parent = parent; \ - node = parent->left; \ - } \ - else \ - { \ - parent->right = CMC_(PFX, _impl_new_node)(_set_, value); \ -\ - if (!parent->right) \ - { \ - _set_->flag = CMC_FLAG_ALLOC; \ - return false; \ - } \ -\ - parent->right->parent = parent; \ - node = parent->right; \ - } \ -\ - CMC_(PFX, _impl_rebalance)(_set_, node); \ - } \ -\ - _set_->count++; \ - _set_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_set_, create); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _remove)(struct SNAME * _set_, V value) \ - { \ - if (CMC_(PFX, _empty)(_set_)) \ - { \ - _set_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - struct CMC_DEF_NODE(SNAME) *node = CMC_(PFX, _impl_get_node)(_set_, value); \ -\ - if (!node) \ - { \ - _set_->flag = CMC_FLAG_NOT_FOUND; \ - return false; \ - } \ -\ - struct CMC_DEF_NODE(SNAME) *temp = NULL, *unbalanced = NULL; \ -\ - bool is_root = node->parent == NULL; \ -\ - if (node->left == NULL && node->right == NULL) \ - { \ - if (is_root) \ - _set_->root = NULL; \ - else \ - { \ - unbalanced = node->parent; \ -\ - if (node->parent->right == node) \ - node->parent->right = NULL; \ - else \ - node->parent->left = NULL; \ - } \ -\ - _set_->alloc->free(node); \ - } \ - else if (node->left == NULL) \ - { \ - if (is_root) \ - { \ - _set_->root = node->right; \ - _set_->root->parent = NULL; \ - } \ - else \ - { \ - unbalanced = node->parent; \ -\ - node->right->parent = node->parent; \ -\ - if (node->parent->right == node) \ - node->parent->right = node->right; \ - else \ - node->parent->left = node->right; \ - } \ -\ - _set_->alloc->free(node); \ - } \ - else if (node->right == NULL) \ - { \ - if (is_root) \ - { \ - _set_->root = node->left; \ - _set_->root->parent = NULL; \ - } \ - else \ - { \ - unbalanced = node->parent; \ -\ - node->left->parent = node->parent; \ -\ - if (node->parent->right == node) \ - node->parent->right = node->left; \ - else \ - node->parent->left = node->left; \ - } \ -\ - _set_->alloc->free(node); \ - } \ - else \ - { \ - temp = node->right; \ - while (temp->left != NULL) \ - temp = temp->left; \ -\ - V temp_value = temp->value; \ -\ - unbalanced = temp->parent; \ -\ - if (temp->left == NULL && temp->right == NULL) \ - { \ - if (temp->parent->right == temp) \ - temp->parent->right = NULL; \ - else \ - temp->parent->left = NULL; \ - } \ - else if (temp->left == NULL) \ - { \ - temp->right->parent = temp->parent; \ -\ - if (temp->parent->right == temp) \ - temp->parent->right = temp->right; \ - else \ - temp->parent->left = temp->right; \ - } \ - else if (temp->right == NULL) \ - { \ - temp->left->parent = temp->parent; \ -\ - if (temp->parent->right == temp) \ - temp->parent->right = temp->left; \ - else \ - temp->parent->left = temp->left; \ - } \ -\ - _set_->alloc->free(temp); \ -\ - node->value = temp_value; \ - } \ -\ - if (unbalanced != NULL) \ - CMC_(PFX, _impl_rebalance)(_set_, unbalanced); \ -\ - if (_set_->count == 0) \ - _set_->root = NULL; \ -\ - _set_->count--; \ - _set_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_set_, delete); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _max)(struct SNAME * _set_, V * value) \ - { \ - if (CMC_(PFX, _empty)(_set_)) \ - { \ - _set_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - struct CMC_DEF_NODE(SNAME) *scan = _set_->root; \ -\ - while (scan->right != NULL) \ - scan = scan->right; \ -\ - if (value) \ - *value = scan->value; \ -\ - _set_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_set_, read); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _min)(struct SNAME * _set_, V * value) \ - { \ - if (CMC_(PFX, _empty)(_set_)) \ - { \ - _set_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - struct CMC_DEF_NODE(SNAME) *scan = _set_->root; \ -\ - while (scan->left != NULL) \ - scan = scan->left; \ -\ - if (value) \ - *value = scan->value; \ -\ - _set_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_set_, read); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _contains)(struct SNAME * _set_, V value) \ - { \ - bool result = CMC_(PFX, _impl_get_node)(_set_, value) != NULL; \ -\ - CMC_CALLBACKS_CALL(_set_, read); \ -\ - return result; \ - } \ -\ - bool CMC_(PFX, _empty)(struct SNAME * _set_) \ - { \ - return _set_->count == 0; \ - } \ -\ - size_t CMC_(PFX, _count)(struct SNAME * _set_) \ - { \ - return _set_->count; \ - } \ -\ - int CMC_(PFX, _flag)(struct SNAME * _set_) \ - { \ - return _set_->flag; \ - } \ -\ - struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_) \ - { \ - struct SNAME *result = CMC_(PFX, _new_custom)(_set_->f_val, _set_->alloc, NULL); \ -\ - if (!result) \ - { \ - _set_->flag = CMC_FLAG_ERROR; \ - return NULL; \ - } \ -\ - CMC_CALLBACKS_ASSIGN(result, _set_->callbacks); \ -\ - if (!CMC_(PFX, _empty)(_set_)) \ - { \ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - if (_set_->f_val->cpy) \ - CMC_(PFX, _insert) \ - (result, _set_->f_val->cpy(CMC_(PFX, _iter_value)(&iter))); \ - else CMC_(PFX, _insert)(result, CMC_(PFX, _iter_value)(&iter)); \ - } \ - } \ -\ - _set_->flag = CMC_FLAG_OK; \ -\ - return result; \ - } \ -\ - bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - _set1_->flag = CMC_FLAG_OK; \ - _set2_->flag = CMC_FLAG_OK; \ -\ - if (_set1_->count != _set2_->count) \ - return false; \ -\ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - if (CMC_(PFX, _impl_get_node)(_set2_, CMC_(PFX, _iter_value)(&iter)) == NULL) \ - return false; \ - } \ -\ - return true; \ - } \ -\ - static struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _impl_new_node)(struct SNAME * _set_, V value) \ - { \ - struct CMC_DEF_NODE(SNAME) *node = _set_->alloc->malloc(sizeof(struct CMC_DEF_NODE(SNAME))); \ -\ - if (!node) \ - return NULL; \ -\ - node->value = value; \ - node->right = NULL; \ - node->left = NULL; \ - node->parent = NULL; \ - node->height = 0; \ -\ - return node; \ - } \ -\ - static struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _impl_get_node)(struct SNAME * _set_, V value) \ - { \ - struct CMC_DEF_NODE(SNAME) *scan = _set_->root; \ -\ - while (scan != NULL) \ - { \ - if (_set_->f_val->cmp(scan->value, value) > 0) \ - scan = scan->left; \ - else if (_set_->f_val->cmp(scan->value, value) < 0) \ - scan = scan->right; \ - else \ - return scan; \ - } \ -\ - return NULL; \ - } \ -\ - static unsigned char CMC_(PFX, _impl_h)(struct CMC_DEF_NODE(SNAME) * node) \ - { \ - if (node == NULL) \ - return 0; \ -\ - return node->height; \ - } \ -\ - static unsigned char CMC_(PFX, _impl_hupdate)(struct CMC_DEF_NODE(SNAME) * node) \ - { \ - if (node == NULL) \ - return 0; \ -\ - unsigned char h_l = CMC_(PFX, _impl_h)(node->left); \ - unsigned char h_r = CMC_(PFX, _impl_h)(node->right); \ -\ - return 1 + (h_l > h_r ? h_l : h_r); \ - } \ -\ - static void CMC_(PFX, _impl_rotate_right)(struct CMC_DEF_NODE(SNAME) * *Z) \ - { \ - struct CMC_DEF_NODE(SNAME) *root = *Z; \ - struct CMC_DEF_NODE(SNAME) *new_root = root->left; \ -\ - if (root->parent != NULL) \ - { \ - if (root->parent->left == root) \ - root->parent->left = new_root; \ - else \ - root->parent->right = new_root; \ - } \ -\ - new_root->parent = root->parent; \ -\ - root->parent = new_root; \ - root->left = new_root->right; \ -\ - if (root->left) \ - root->left->parent = root; \ -\ - new_root->right = root; \ -\ - root->height = CMC_(PFX, _impl_hupdate)(root); \ - new_root->height = CMC_(PFX, _impl_hupdate)(new_root); \ -\ - *Z = new_root; \ - } \ -\ - static void CMC_(PFX, _impl_rotate_left)(struct CMC_DEF_NODE(SNAME) * *Z) \ - { \ - struct CMC_DEF_NODE(SNAME) *root = *Z; \ - struct CMC_DEF_NODE(SNAME) *new_root = root->right; \ -\ - if (root->parent != NULL) \ - { \ - if (root->parent->right == root) \ - root->parent->right = new_root; \ - else \ - root->parent->left = new_root; \ - } \ -\ - new_root->parent = root->parent; \ -\ - root->parent = new_root; \ - root->right = new_root->left; \ -\ - if (root->right) \ - root->right->parent = root; \ -\ - new_root->left = root; \ -\ - root->height = CMC_(PFX, _impl_hupdate)(root); \ - new_root->height = CMC_(PFX, _impl_hupdate)(new_root); \ -\ - *Z = new_root; \ - } \ -\ - static void CMC_(PFX, _impl_rebalance)(struct SNAME * _set_, struct CMC_DEF_NODE(SNAME) * node) \ - { \ - struct CMC_DEF_NODE(SNAME) *scan = node, *child = NULL; \ -\ - int balance; \ - bool is_root = false; \ -\ - while (scan != NULL) \ - { \ - if (scan->parent == NULL) \ - is_root = true; \ -\ - scan->height = CMC_(PFX, _impl_hupdate)(scan); \ - balance = CMC_(PFX, _impl_h)(scan->right) - CMC_(PFX, _impl_h)(scan->left); \ -\ - if (balance >= 2) \ - { \ - child = scan->right; \ -\ - if (CMC_(PFX, _impl_h)(child->right) < CMC_(PFX, _impl_h)(child->left)) \ - CMC_(PFX, _impl_rotate_right)(&(scan->right)); \ -\ - CMC_(PFX, _impl_rotate_left)(&scan); \ - } \ - else if (balance <= -2) \ - { \ - child = scan->left; \ -\ - if (CMC_(PFX, _impl_h)(child->left) < CMC_(PFX, _impl_h)(child->right)) \ - CMC_(PFX, _impl_rotate_left)(&(scan->left)); \ -\ - CMC_(PFX, _impl_rotate_right)(&scan); \ - } \ -\ - if (is_root) \ - { \ - _set_->root = scan; \ - is_root = false; \ - } \ -\ - scan = scan->parent; \ - } \ - } - -#endif /* CMC_CMC_TREESET_H */ diff --git a/src/ext_cmc_deque.h b/src/ext_cmc_deque.h deleted file mode 100644 index af2b2d3..0000000 --- a/src/ext_cmc_deque.h +++ /dev/null @@ -1,472 +0,0 @@ -/** - * Copyright (c) 2019 Leonardo Vencovsky - * - * This file is part of the C Macro Collections Libray. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * ext_cmc_deque.h - * - * Creation Date: 25/05/2020 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -#ifndef CMC_EXT_CMC_DEQUE_H -#define CMC_EXT_CMC_DEQUE_H - -#include "cor_core.h" - -/** - * All the EXT parts of CMC Deque. - */ -#define CMC_EXT_CMC_DEQUE_PARTS INIT, ITER, STR - -/** - * INIT - * - * The part 'INIT' gives a new way of initializing a collection. The collection - * struct is not heap allocated, only its internal structure (nodes, buffers). - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_DEQUE_INIT(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_EXT_CMC_DEQUE_INIT_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_DEQUE_INIT_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_DEQUE_INIT_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_DEQUE_INIT_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_DEQUE_INIT_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -/* INIT Extension can't be used with opaque struct */ -#define CMC_EXT_CMC_DEQUE_INIT_PRIVATE_HEADER(PARAMS) -#define CMC_EXT_CMC_DEQUE_INIT_PRIVATE_SOURCE(PARAMS) - -#define CMC_EXT_CMC_DEQUE_INIT_HEADER_(PFX, SNAME, V) \ -\ - struct SNAME CMC_(PFX, _init)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME CMC_(PFX, _init_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks); \ - void CMC_(PFX, _release)(struct SNAME _deque_); - -#define CMC_EXT_CMC_DEQUE_INIT_SOURCE_(PFX, SNAME, V) \ -\ - struct SNAME CMC_(PFX, _init)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - return CMC_(PFX, _init_custom)(capacity, f_val, NULL, NULL); \ - } \ -\ - struct SNAME CMC_(PFX, _init_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, \ - struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - struct SNAME _deque_ = { 0 }; \ -\ - if (capacity < 1) \ - return _deque_; \ -\ - if (!f_val) \ - return _deque_; \ -\ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ -\ - _deque_.buffer = alloc->calloc(capacity, sizeof(V)); \ -\ - if (!_deque_.buffer) \ - return _deque_; \ -\ - _deque_.capacity = capacity; \ - _deque_.count = 0; \ - _deque_.front = 0; \ - _deque_.back = 0; \ - _deque_.flag = CMC_FLAG_OK; \ - _deque_.f_val = f_val; \ - _deque_.alloc = alloc; \ - CMC_CALLBACKS_ASSIGN(&_deque_, callbacks); \ -\ - return _deque_; \ - } \ -\ - void CMC_(PFX, _release)(struct SNAME _deque_) \ - { \ - if (_deque_.f_val->free) \ - { \ - for (size_t i = _deque_.front, j = 0; j < _deque_.count; j++) \ - { \ - _deque_.f_val->free(_deque_.buffer[i]); \ -\ - i = (i + 1) % _deque_.capacity; \ - } \ - } \ -\ - _deque_.alloc->free(_deque_.buffer); \ - } - -/** - * ITER - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_DEQUE_ITER(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_EXT_CMC_DEQUE_ITER_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_DEQUE_ITER_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_DEQUE_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_DEQUE_ITER_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_DEQUE_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_DEQUE_ITER_PRIVATE_HEADER(PARAMS) \ - CMC_EXT_CMC_DEQUE_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_DEQUE_ITER_PRIVATE_SOURCE(PARAMS) \ - CMC_EXT_CMC_DEQUE_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_DEQUE_ITER_HEADER_(PFX, SNAME, V) \ -\ - /* Deque Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target deque */ \ - struct SNAME *target; \ -\ - /* Cursor's position (index) */ \ - size_t cursor; \ -\ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ -\ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ -\ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ -\ - /* Iterator Initialization */ \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ - /* Iterator Access */ \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); - -#define CMC_EXT_CMC_DEQUE_ITER_SOURCE_(PFX, SNAME, V) \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.cursor = target->front; \ - iter.index = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ -\ - return iter; \ - } \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ -\ - if (!CMC_(PFX, _empty)(target)) \ - { \ - if (iter.target->back == 0) \ - iter.cursor = iter.target->capacity - 1; \ - else \ - iter.cursor = iter.target->back - 1; \ -\ - iter.index = iter.target->count - 1; \ - } \ - else \ - { \ - iter.cursor = 0; \ - iter.index = 0; \ - } \ -\ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ -\ - return iter; \ - } \ -\ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ -\ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ -\ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->target->front; \ - iter->index = 0; \ - iter->start = true; \ - iter->end = false; \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - if (iter->target->back == 0) \ - iter->cursor = iter->target->capacity - 1; \ - else \ - iter->cursor = iter->target->back - 1; \ -\ - iter->index = iter->target->count - 1; \ -\ - iter->start = false; \ - iter->end = true; \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - iter->start = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor = (iter->cursor + 1) % (iter->target->capacity); \ - iter->index++; \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1; \ - iter->index--; \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->index + steps >= iter->target->count) \ - return false; \ -\ - iter->start = CMC_(PFX, _empty)(iter->target); \ -\ - iter->index += steps; \ - iter->cursor = (iter->cursor + steps) % iter->target->capacity; \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->index < steps) \ - return false; \ -\ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - iter->index -= steps; \ -\ - /* Prevent underflow */ \ - if (iter->cursor < steps) \ - iter->cursor += iter->target->capacity; \ -\ - iter->cursor -= steps; \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ -\ - if (iter->index > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ - else if (iter->index < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ -\ - return true; \ - } \ -\ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ -\ - return iter->target->buffer[iter->cursor]; \ - } \ -\ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return NULL; \ -\ - return &(iter->target->buffer[iter->cursor]); \ - } \ -\ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->index; \ - } - -/** - * STR - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_DEQUE_STR(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_EXT_CMC_DEQUE_STR_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_DEQUE_STR_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_DEQUE_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_DEQUE_STR_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_DEQUE_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_DEQUE_STR_PRIVATE_HEADER(PARAMS) \ - CMC_EXT_CMC_DEQUE_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_DEQUE_STR_PRIVATE_SOURCE(PARAMS) \ - CMC_EXT_CMC_DEQUE_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_DEQUE_STR_HEADER_(PFX, SNAME, V) \ -\ - bool CMC_(PFX, _to_string)(struct SNAME * _deque_, FILE * fptr); \ - bool CMC_(PFX, _print)(struct SNAME * _deque_, FILE * fptr, const char *start, const char *separator, \ - const char *end); - -#define CMC_EXT_CMC_DEQUE_STR_SOURCE_(PFX, SNAME, V) \ -\ - bool CMC_(PFX, _to_string)(struct SNAME * _deque_, FILE * fptr) \ - { \ - struct SNAME *d_ = _deque_; \ -\ - return 0 <= fprintf(fptr, \ - "struct %s<%s> " \ - "at %p { " \ - "buffer:%p, " \ - "capacity:%" PRIuMAX ", " \ - "count:%" PRIuMAX ", " \ - "front:%" PRIuMAX ", " \ - "back:%" PRIuMAX ", " \ - "flag:%d, " \ - "f_val:%p, " \ - "alloc:%p, " \ - "callbacks:%p }", \ - CMC_TO_STRING(SNAME), CMC_TO_STRING(V), d_, d_->buffer, d_->capacity, d_->count, \ - d_->front, d_->back, d_->flag, d_->f_val, d_->alloc, CMC_CALLBACKS_GET(d_)); \ - } \ -\ - bool CMC_(PFX, _print)(struct SNAME * _deque_, FILE * fptr, const char *start, const char *separator, \ - const char *end) \ - { \ - fprintf(fptr, "%s", start); \ -\ - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \ - { \ - if (!_deque_->f_val->str(fptr, _deque_->buffer[i])) \ - return false; \ -\ - i = (i + 1) % _deque_->capacity; \ -\ - if (j + 1 < _deque_->count) \ - fprintf(fptr, "%s", separator); \ - } \ -\ - fprintf(fptr, "%s", end); \ -\ - return true; \ - } - -#endif /* CMC_EXT_CMC_DEQUE_H */ diff --git a/src/ext_cmc_hashbidimap.h b/src/ext_cmc_hashbidimap.h deleted file mode 100644 index 89e7984..0000000 --- a/src/ext_cmc_hashbidimap.h +++ /dev/null @@ -1,140 +0,0 @@ -/** - * Copyright (c) 2019 Leonardo Vencovsky - * - * This file is part of the C Macro Collections Libray. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * ext_cmc_hashbidimap.h - * - * Creation Date: 26/05/2020 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -#ifndef CMC_EXT_CMC_HASHBIDIMAP_H -#define CMC_EXT_CMC_HASHBIDIMAP_H - -#include "cor_core.h" - -/** - * All the EXT parts of CMC HashBidiMap. - */ -#define CMC_EXT_CMC_HASHBIDIMAP_PARTS STR - -/** - * STR - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_HASHBIDIMAP_STR(ACCESS, FILE, PARAMS) \ - CMC_(CMC_(CMC_EXT_CMC_HASHBIDIMAP_STR_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_HASHBIDIMAP_STR_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHBIDIMAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHBIDIMAP_STR_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_HASHBIDIMAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHBIDIMAP_STR_PRIVATE_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHBIDIMAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHBIDIMAP_STR_PRIVATE_SOURCE(PARAMS) \ - CMC_EXT_CMC_HASHBIDIMAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHBIDIMAP_STR_HEADER_(PFX, SNAME, K, V) \ -\ - bool CMC_(PFX, _to_string)(struct SNAME * _map_, FILE * fptr); \ - bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr, const char *start, const char *separator, \ - const char *end, const char *key_val_sep); - -#define CMC_EXT_CMC_HASHBIDIMAP_STR_SOURCE_(PFX, SNAME, K, V) \ -\ - bool CMC_(PFX, _to_string)(struct SNAME * _map_, FILE * fptr) \ - { \ - struct SNAME *m_ = _map_; \ -\ - return 0 <= fprintf(fptr, \ - "struct %s<%s, %s> " \ - "at %p { " \ - "buffer:%p, " \ - "capacity:%" PRIuMAX ", " \ - "count:%" PRIuMAX ", " \ - "load:%lf, " \ - "flag:%d, " \ - "f_key:%p, " \ - "f_val:%p, " \ - "alloc:%p, " \ - "callbacks:%p }", \ - CMC_TO_STRING(SNAME), CMC_TO_STRING(K), CMC_TO_STRING(V), m_, m_->buffer, m_->capacity, \ - m_->count, m_->load, m_->flag, m_->f_key, m_->f_val, m_->alloc, CMC_CALLBACKS_GET(m_)); \ - } \ -\ - bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr, const char *start, const char *separator, \ - const char *end, const char *key_val_sep) \ - { \ - fprintf(fptr, "%s", start); \ -\ - size_t last = 0; \ - for (size_t i = _map_->capacity; i > 0; i--) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = _map_->buffer[i - 1][0]; \ -\ - if (entry && entry != CMC_ENTRY_DELETED) \ - { \ - last = i - 1; \ - break; \ - } \ - } \ -\ - for (size_t i = 0; i < _map_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = _map_->buffer[i][0]; \ -\ - if (entry && entry != CMC_ENTRY_DELETED) \ - { \ - if (!_map_->f_key->str(fptr, entry->key)) \ - return false; \ -\ - fprintf(fptr, "%s", key_val_sep); \ -\ - if (!_map_->f_val->str(fptr, entry->value)) \ - return false; \ -\ - if (i + 1 < last) \ - fprintf(fptr, "%s", separator); \ - } \ - } \ -\ - fprintf(fptr, "%s", end); \ -\ - return true; \ - } - -#endif /* CMC_EXT_CMC_HASHBIDIMAP_H */ diff --git a/src/ext_cmc_hashmap.h b/src/ext_cmc_hashmap.h deleted file mode 100644 index 57d0cdf..0000000 --- a/src/ext_cmc_hashmap.h +++ /dev/null @@ -1,578 +0,0 @@ -/** - * Copyright (c) 2019 Leonardo Vencovsky - * - * This file is part of the C Macro Collections Libray. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * ext_cmc_hashmap.h - * - * Creation Date: 25/05/2020 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -#ifndef CMC_EXT_CMC_HASHMAP_H -#define CMC_EXT_CMC_HASHMAP_H - -#include "cor_core.h" - -/** - * All the EXT parts of CMC HashMap. - */ -#define CMC_EXT_CMC_HASHMAP_PARTS INIT, ITER, STR - -/** - * INIT - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_HASHMAP_INIT(ACCESS, FILE, PARAMS) \ - CMC_(CMC_(CMC_EXT_CMC_HASHMAP_INIT_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_HASHMAP_INIT_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHMAP_INIT_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHMAP_INIT_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_HASHMAP_INIT_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHMAP_INIT_PRIVATE_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHMAP_INIT_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHMAP_INIT_PRIVATE_SOURCE(PARAMS) \ - CMC_EXT_CMC_HASHMAP_INIT_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHMAP_INIT_HEADER_(PFX, SNAME, K, V) \ -\ - struct SNAME CMC_(PFX, _init)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \ - struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME CMC_(PFX, _init_custom)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \ - struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks); \ - void CMC_(PFX, _release)(struct SNAME _map_); - -#define CMC_EXT_CMC_HASHMAP_INIT_SOURCE_(PFX, SNAME, K, V) \ -\ - struct SNAME CMC_(PFX, _init)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \ - struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - return CMC_(PFX, _init_custom)(capacity, load, f_key, f_val, NULL, NULL); \ - } \ -\ - struct SNAME CMC_(PFX, _init_custom)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \ - struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \ - struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - struct SNAME _map_ = { 0 }; \ -\ - if (capacity == 0 || load <= 0 || load >= 1) \ - return _map_; \ -\ - /* Prevent integer overflow */ \ - if (capacity >= UINTMAX_MAX * load) \ - return _map_; \ -\ - if (!f_key || !f_val) \ - return _map_; \ -\ - size_t real_capacity = CMC_(PFX, _impl_calculate_size)(capacity / load); \ -\ - if (!alloc) \ - alloc = &cmc_alloc_node_default; \ -\ - _map_.buffer = alloc->calloc(real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME))); \ -\ - if (!_map_.buffer) \ - return _map_; \ -\ - _map_.count = 0; \ - _map_.capacity = real_capacity; \ - _map_.load = load; \ - _map_.flag = CMC_FLAG_OK; \ - _map_.f_key = f_key; \ - _map_.f_val = f_val; \ - _map_.alloc = alloc; \ - CMC_CALLBACKS_ASSIGN(&_map_, callbacks); \ -\ - return _map_; \ - } \ -\ - void CMC_(PFX, _release)(struct SNAME _map_) \ - { \ - if (_map_.f_key->free || _map_.f_val->free) \ - { \ - for (size_t i = 0; i < _map_.capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = &(_map_.buffer[i]); \ -\ - if (entry->state == CMC_ES_FILLED) \ - { \ - if (_map_.f_key->free) \ - _map_.f_key->free(entry->key); \ - if (_map_.f_val->free) \ - _map_.f_val->free(entry->value); \ - } \ - } \ - } \ -\ - _map_.alloc->free(_map_.buffer); \ - } - -/** - * ITER - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_HASHMAP_ITER(ACCESS, FILE, PARAMS) \ - CMC_(CMC_(CMC_EXT_CMC_HASHMAP_ITER_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_HASHMAP_ITER_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHMAP_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHMAP_ITER_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_HASHMAP_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHMAP_ITER_PRIVATE_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHMAP_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHMAP_ITER_PRIVATE_SOURCE(PARAMS) \ - CMC_EXT_CMC_HASHMAP_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHMAP_ITER_HEADER_(PFX, SNAME, K, V) \ -\ - /* HashMap Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target hashmap */ \ - struct SNAME *target; \ -\ - /* Cursor's position (index) */ \ - size_t cursor; \ -\ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ -\ - /* The index of the first element */ \ - size_t first; \ -\ - /* The index of the last element */ \ - size_t last; \ -\ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ -\ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ -\ - /* Iterator Initialization */ \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ - /* Iterator Access */ \ - K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter); \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); - -#define CMC_EXT_CMC_HASHMAP_ITER_SOURCE_(PFX, SNAME, K, V) \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.cursor = 0; \ - iter.index = 0; \ - iter.first = 0; \ - iter.last = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ -\ - if (!CMC_(PFX, _empty)(target)) \ - { \ - for (size_t i = 0; i < target->capacity; i++) \ - { \ - if (target->buffer[i].state == CMC_ES_FILLED) \ - { \ - iter.first = i; \ - break; \ - } \ - } \ -\ - iter.cursor = iter.first; \ -\ - for (size_t i = target->capacity; i > 0; i--) \ - { \ - if (target->buffer[i - 1].state == CMC_ES_FILLED) \ - { \ - iter.last = i - 1; \ - break; \ - } \ - } \ - } \ -\ - return iter; \ - } \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.cursor = 0; \ - iter.index = 0; \ - iter.first = 0; \ - iter.last = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ -\ - if (!CMC_(PFX, _empty)(target)) \ - { \ - for (size_t i = 0; i < target->capacity; i++) \ - { \ - if (target->buffer[i].state == CMC_ES_FILLED) \ - { \ - iter.first = i; \ - break; \ - } \ - } \ -\ - for (size_t i = target->capacity; i > 0; i--) \ - { \ - if (target->buffer[i - 1].state == CMC_ES_FILLED) \ - { \ - iter.last = i - 1; \ - break; \ - } \ - } \ -\ - iter.cursor = iter.last; \ - iter.index = target->count - 1; \ - } \ -\ - return iter; \ - } \ -\ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ -\ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ -\ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->first; \ - iter->index = 0; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->last; \ - iter->index = iter->target->count - 1; \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->end = true; \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - iter->start = CMC_(PFX, _empty)(iter->target); \ -\ - struct CMC_DEF_ENTRY(SNAME) *scan = &(iter->target->buffer[iter->cursor]); \ -\ - iter->index++; \ -\ - while (1) \ - { \ - iter->cursor++; \ - scan = &(iter->target->buffer[iter->cursor]); \ -\ - if (scan->state == CMC_ES_FILLED) \ - break; \ - } \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - struct CMC_DEF_ENTRY(SNAME) *scan = &(iter->target->buffer[iter->cursor]); \ -\ - iter->index--; \ -\ - while (1) \ - { \ - iter->cursor--; \ - scan = &(iter->target->buffer[iter->cursor]); \ -\ - if (scan->state == CMC_ES_FILLED) \ - break; \ - } \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->index + steps >= iter->target->count) \ - return false; \ -\ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_next)(iter); \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->index < steps) \ - return false; \ -\ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_prev)(iter); \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ -\ - if (iter->index > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ - else if (iter->index < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ -\ - return true; \ - } \ -\ - K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (K){ 0 }; \ -\ - return iter->target->buffer[iter->cursor].key; \ - } \ -\ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ -\ - return iter->target->buffer[iter->cursor].value; \ - } \ -\ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return NULL; \ -\ - return &(iter->target->buffer[iter->cursor].value); \ - } \ -\ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->index; \ - } - -/** - * STR - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_HASHMAP_STR(ACCESS, FILE, PARAMS) \ - CMC_(CMC_(CMC_EXT_CMC_HASHMAP_STR_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_HASHMAP_STR_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHMAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHMAP_STR_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_HASHMAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHMAP_STR_PRIVATE_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHMAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHMAP_STR_PRIVATE_SOURCE(PARAMS) \ - CMC_EXT_CMC_HASHMAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHMAP_STR_HEADER_(PFX, SNAME, K, V) \ -\ - bool CMC_(PFX, _to_string)(struct SNAME * _map_, FILE * fptr); \ - bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr, const char *start, const char *separator, \ - const char *end, const char *key_val_sep); - -#define CMC_EXT_CMC_HASHMAP_STR_SOURCE_(PFX, SNAME, K, V) \ -\ - bool CMC_(PFX, _to_string)(struct SNAME * _map_, FILE * fptr) \ - { \ - struct SNAME *m_ = _map_; \ -\ - return 0 <= fprintf(fptr, \ - "struct %s<%s, %s> " \ - "at %p { " \ - "buffer:%p, " \ - "capacity:%" PRIuMAX ", " \ - "count:%" PRIuMAX ", " \ - "load:%lf, " \ - "flag:%d, " \ - "f_key:%p, " \ - "f_val:%p, " \ - "alloc:%p, " \ - "callbacks:%p }", \ - CMC_TO_STRING(SNAME), CMC_TO_STRING(K), CMC_TO_STRING(V), m_, m_->buffer, m_->capacity, \ - m_->count, m_->load, m_->flag, m_->f_key, m_->f_val, m_->alloc, CMC_CALLBACKS_GET(m_)); \ - } \ -\ - bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr, const char *start, const char *separator, \ - const char *end, const char *key_val_sep) \ - { \ - fprintf(fptr, "%s", start); \ -\ - size_t last = 0; \ - for (size_t i = _map_->capacity; i > 0; i--) \ - { \ - if ((_map_->buffer[i - 1]).state == CMC_ES_FILLED) \ - { \ - last = i - 1; \ - break; \ - } \ - } \ -\ - for (size_t i = 0; i < _map_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = &(_map_->buffer[i]); \ -\ - if (entry->state == CMC_ES_FILLED) \ - { \ - if (!_map_->f_key->str(fptr, entry->key)) \ - return false; \ -\ - fprintf(fptr, "%s", key_val_sep); \ -\ - if (!_map_->f_val->str(fptr, entry->value)) \ - return false; \ -\ - if (i + 1 < last) \ - fprintf(fptr, "%s", separator); \ - } \ - } \ -\ - fprintf(fptr, "%s", end); \ -\ - return true; \ - } - -#endif /* CMC_EXT_CMC_HASHMAP_H */ diff --git a/src/ext_cmc_hashmultimap.h b/src/ext_cmc_hashmultimap.h deleted file mode 100644 index e355397..0000000 --- a/src/ext_cmc_hashmultimap.h +++ /dev/null @@ -1,503 +0,0 @@ -/** - * Copyright (c) 2019 Leonardo Vencovsky - * - * This file is part of the C Macro Collections Libray. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * ext_cmc_hashmultimap.h - * - * Creation Date: 29/05/2020 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -#ifndef CMC_EXT_CMC_HASHMULTIMAP_H -#define CMC_EXT_CMC_HASHMULTIMAP_H - -#include "cor_core.h" - -/** - * All the EXT parts of CMC HashMultiMap. - */ -#define CMC_EXT_CMC_HASHMULTIMAP_PARTS ITER, STR - -/** - * ITER - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_HASHMULTIMAP_ITER(ACCESS, FILE, PARAMS) \ - CMC_(CMC_(CMC_EXT_CMC_HASHMULTIMAP_ITER_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_HASHMULTIMAP_ITER_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHMULTIMAP_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHMULTIMAP_ITER_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_HASHMULTIMAP_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHMULTIMAP_ITER_PRIVATE_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHMULTIMAP_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHMULTIMAP_ITER_PRIVATE_SOURCE(PARAMS) \ - CMC_EXT_CMC_HASHMULTIMAP_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHMULTIMAP_ITER_HEADER_(PFX, SNAME, K, V) \ -\ - /* HashMultiMap Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target hashmultimap */ \ - struct SNAME *target; \ -\ - /* Current entry */ \ - struct CMC_DEF_ENTRY(SNAME) * curr_entry; \ -\ - /* Cursor`s position (index) */ \ - size_t cursor; \ -\ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ -\ - /* The index of the first element */ \ - size_t first; \ -\ - /* The index of the last element */ \ - size_t last; \ -\ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ -\ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ -\ - /* Iterator Initialization */ \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ - /* Iterator Access */ \ - K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter); \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); - -#define CMC_EXT_CMC_HASHMULTIMAP_ITER_SOURCE_(PFX, SNAME, K, V) \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.curr_entry = NULL; \ - iter.cursor = 0; \ - iter.index = 0; \ - iter.first = 0; \ - iter.last = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ -\ - if (!CMC_(PFX, _empty)(target)) \ - { \ - for (size_t i = 0; i < target->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = target->buffer[i][0]; \ -\ - if (entry && entry != CMC_ENTRY_DELETED) \ - { \ - iter.curr_entry = target->buffer[i][0]; \ - iter.first = i; \ - break; \ - } \ - } \ -\ - iter.cursor = iter.first; \ -\ - for (size_t i = target->capacity; i > 0; i--) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = target->buffer[i - 1][1]; \ -\ - if (entry && entry != CMC_ENTRY_DELETED) \ - { \ - iter.last = i - 1; \ - break; \ - } \ - } \ - } \ -\ - return iter; \ - } \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.curr_entry = NULL; \ - iter.cursor = 0; \ - iter.index = 0; \ - iter.first = 0; \ - iter.last = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ -\ - if (!CMC_(PFX, _empty)(target)) \ - { \ - for (size_t i = 0; i < target->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = target->buffer[i][0]; \ -\ - if (entry && entry != CMC_ENTRY_DELETED) \ - { \ - iter.first = i; \ - break; \ - } \ - } \ -\ - for (size_t i = target->capacity; i > 0; i--) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = target->buffer[i - 1][1]; \ -\ - if (entry && entry != CMC_ENTRY_DELETED) \ - { \ - iter.curr_entry = target->buffer[i - 1][1]; \ - iter.last = i - 1; \ - break; \ - } \ - } \ -\ - iter.cursor = iter.last; \ - iter.index = target->count - 1; \ - } \ -\ - return iter; \ - } \ -\ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ -\ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ -\ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->first; \ - iter->index = 0; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - iter->curr_entry = iter->target->buffer[iter->first][0]; \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->last; \ - iter->index = iter->target->count - 1; \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->end = true; \ - iter->curr_entry = iter->target->buffer[iter->last][1]; \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->curr_entry->next != NULL) \ - { \ - iter->curr_entry = iter->curr_entry->next; \ - iter->index++; \ - } \ - else \ - { \ - if (iter->cursor == iter->last) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - iter->cursor++; \ -\ - while (iter->target->buffer[iter->cursor][0] == NULL) \ - iter->cursor++; \ -\ - iter->curr_entry = iter->target->buffer[iter->cursor][0]; \ -\ - iter->index++; \ - } \ -\ - iter->start = CMC_(PFX, _empty)(iter->target); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->curr_entry->prev != NULL) \ - { \ - iter->curr_entry = iter->curr_entry->prev; \ - iter->index--; \ - } \ - else \ - { \ - if (iter->cursor == iter->first) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - iter->cursor--; \ -\ - while (iter->target->buffer[iter->cursor][1] == NULL) \ - iter->cursor--; \ -\ - iter->curr_entry = iter->target->buffer[iter->cursor][1]; \ -\ - iter->index--; \ - } \ -\ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->index + steps >= iter->target->count) \ - return false; \ -\ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_next)(iter); \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->index < steps) \ - return false; \ -\ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_prev)(iter); \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ -\ - if (iter->index > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ - else if (iter->index < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ -\ - return true; \ - } \ -\ - K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (K){ 0 }; \ -\ - return iter->curr_entry->key; \ - } \ -\ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ -\ - return iter->curr_entry->value; \ - } \ -\ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return NULL; \ -\ - return &(iter->curr_entry->value); \ - } \ -\ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->index; \ - } - -/** - * STR - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_HASHMULTIMAP_STR(ACCESS, FILE, PARAMS) \ - CMC_(CMC_(CMC_EXT_CMC_HASHMULTIMAP_STR_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_HASHMULTIMAP_STR_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHMULTIMAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHMULTIMAP_STR_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_HASHMULTIMAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHMULTIMAP_STR_PRIVATE_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHMULTIMAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHMULTIMAP_STR_PRIVATE_SOURCE(PARAMS) \ - CMC_EXT_CMC_HASHMULTIMAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHMULTIMAP_STR_HEADER_(PFX, SNAME, K, V) \ -\ - bool CMC_(PFX, _to_string)(struct SNAME * _map_, FILE * fptr); \ - bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr, const char *start, const char *separator, \ - const char *end, const char *key_val_sep); - -#define CMC_EXT_CMC_HASHMULTIMAP_STR_SOURCE_(PFX, SNAME, K, V) \ -\ - bool CMC_(PFX, _to_string)(struct SNAME * _map_, FILE * fptr) \ - { \ - struct SNAME *m_ = _map_; \ -\ - return 0 <= fprintf(fptr, \ - "struct %s<%s, %s> " \ - "at %p { " \ - "buffer:%p, " \ - "capacity:%" PRIuMAX ", " \ - "count:%" PRIuMAX ", " \ - "load:%lf, " \ - "flag:%d, " \ - "f_key:%p, " \ - "f_val:%p, " \ - "alloc:%p, " \ - "callbacks:%p }", \ - CMC_TO_STRING(SNAME), CMC_TO_STRING(K), CMC_TO_STRING(V), m_, m_->buffer, m_->capacity, \ - m_->count, m_->load, m_->flag, m_->f_key, m_->f_val, m_->alloc, CMC_CALLBACKS_GET(m_)); \ - } \ -\ - bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr, const char *start, const char *separator, \ - const char *end, const char *key_val_sep) \ - { \ - fprintf(fptr, "%s", start); \ -\ - size_t last = 0; \ - for (size_t i = _map_->capacity; i > 0; i--) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = _map_->buffer[i - 1][1]; \ -\ - if (entry && entry != CMC_ENTRY_DELETED) \ - { \ - last = i - 1; \ - break; \ - } \ - } \ -\ - for (size_t i = 0; i < _map_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[i][0]; \ -\ - while (scan != NULL) \ - { \ - if (!_map_->f_key->str(fptr, scan->key)) \ - return false; \ -\ - fprintf(fptr, "%s", key_val_sep); \ -\ - if (!_map_->f_val->str(fptr, scan->value)) \ - return false; \ -\ - scan = scan->next; \ -\ - if (i + 1 < last) \ - fprintf(fptr, "%s", separator); \ - } \ - } \ -\ - fprintf(fptr, "%s", end); \ -\ - return true; \ - } - -#endif /* CMC_EXT_CMC_HASHMULTIMAP_H */ diff --git a/src/ext_cmc_hashmultiset.h b/src/ext_cmc_hashmultiset.h deleted file mode 100644 index c3727f0..0000000 --- a/src/ext_cmc_hashmultiset.h +++ /dev/null @@ -1,749 +0,0 @@ -/** - * Copyright (c) 2019 Leonardo Vencovsky - * - * This file is part of the C Macro Collections Libray. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * ext_cmc_hashmultiset.h - * - * Creation Date: 30/05/2020 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -#ifndef CMC_EXT_CMC_HASHMULTISET_H -#define CMC_EXT_CMC_HASHMULTISET_H - -#include "cor_core.h" - -/** - * All the EXT parts of CMC HashMultiSet. - */ -#define CMC_EXT_CMC_HASHMULTISET_PARTS ITER, SETF, STR - -/** - * ITER - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_HASHMULTISET_ITER(ACCESS, FILE, PARAMS) \ - CMC_(CMC_(CMC_EXT_CMC_HASHMULTISET_ITER_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_HASHMULTISET_ITER_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHMULTISET_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHMULTISET_ITER_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_HASHMULTISET_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHMULTISET_ITER_PRIVATE_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHMULTISET_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHMULTISET_ITER_PRIVATE_SOURCE(PARAMS) \ - CMC_EXT_CMC_HASHMULTISET_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHMULTISET_ITER_HEADER_(PFX, SNAME, V) \ -\ - /* HashMultiSet Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target HashMultiset */ \ - struct SNAME *target; \ -\ - /* Cursor's position (index) */ \ - size_t cursor; \ -\ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ -\ - /* The index of the first element */ \ - size_t first; \ -\ - /* The index of the last element */ \ - size_t last; \ -\ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ -\ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ -\ - /* Iterator Initialization */ \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ - /* Iterator Access */ \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_multiplicity)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); - -#define CMC_EXT_CMC_HASHMULTISET_ITER_SOURCE_(PFX, SNAME, V) \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.cursor = 0; \ - iter.index = 0; \ - iter.first = 0; \ - iter.last = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ -\ - if (!CMC_(PFX, _empty)(target)) \ - { \ - for (size_t i = 0; i < target->capacity; i++) \ - { \ - if (target->buffer[i].state == CMC_ES_FILLED) \ - { \ - iter.first = i; \ - break; \ - } \ - } \ -\ - iter.cursor = iter.first; \ -\ - for (size_t i = target->capacity; i > 0; i--) \ - { \ - if (target->buffer[i - 1].state == CMC_ES_FILLED) \ - { \ - iter.last = i - 1; \ - break; \ - } \ - } \ - } \ -\ - return iter; \ - } \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.cursor = 0; \ - iter.index = 0; \ - iter.first = 0; \ - iter.last = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ -\ - if (!CMC_(PFX, _empty)(target)) \ - { \ - for (size_t i = 0; i < target->capacity; i++) \ - { \ - if (target->buffer[i].state == CMC_ES_FILLED) \ - { \ - iter.first = i; \ - break; \ - } \ - } \ -\ - for (size_t i = target->capacity; i > 0; i--) \ - { \ - if (target->buffer[i - 1].state == CMC_ES_FILLED) \ - { \ - iter.last = i - 1; \ - break; \ - } \ - } \ -\ - iter.cursor = iter.last; \ - iter.index = target->count - 1; \ - } \ -\ - return iter; \ - } \ -\ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ -\ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ -\ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->first; \ - iter->index = 0; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->last; \ - iter->index = iter->target->count - 1; \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->end = true; \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - iter->start = CMC_(PFX, _empty)(iter->target); \ -\ - struct CMC_DEF_ENTRY(SNAME) *scan = &(iter->target->buffer[iter->cursor]); \ -\ - iter->index++; \ -\ - while (1) \ - { \ - iter->cursor++; \ - scan = &(iter->target->buffer[iter->cursor]); \ -\ - if (scan->state == CMC_ES_FILLED) \ - break; \ - } \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - struct CMC_DEF_ENTRY(SNAME) *scan = &(iter->target->buffer[iter->cursor]); \ -\ - iter->index--; \ -\ - while (1) \ - { \ - iter->cursor--; \ - scan = &(iter->target->buffer[iter->cursor]); \ -\ - if (scan->state == CMC_ES_FILLED) \ - break; \ - } \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->index + steps >= iter->target->count) \ - return false; \ -\ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_next)(iter); \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->index < steps) \ - return false; \ -\ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_prev)(iter); \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ -\ - if (iter->index > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ - else if (iter->index < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ -\ - return true; \ - } \ -\ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ -\ - return iter->target->buffer[iter->cursor].value; \ - } \ -\ - size_t CMC_(PFX, _iter_multiplicity)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return 0; \ -\ - return iter->target->buffer[iter->cursor].multiplicity; \ - } \ -\ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->index; \ - } - -/** - * SETF - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_HASHMULTISET_SETF(ACCESS, FILE, PARAMS) \ - CMC_(CMC_(CMC_EXT_CMC_HASHMULTISET_SETF_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_HASHMULTISET_SETF_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHMULTISET_SETF_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHMULTISET_SETF_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_HASHMULTISET_SETF_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHMULTISET_SETF_PRIVATE_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHMULTISET_SETF_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHMULTISET_SETF_PRIVATE_SOURCE(PARAMS) \ - CMC_EXT_CMC_HASHMULTISET_SETF_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHMULTISET_SETF_HEADER_(PFX, SNAME, V) \ -\ - /* Set Operations */ \ - struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _summation)(struct SNAME * _set1_, struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, struct SNAME * _set2_); \ - bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_); \ - bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, struct SNAME * _set2_); \ - bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, struct SNAME * _set2_); \ - bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, struct SNAME * _set2_); \ - bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, struct SNAME * _set2_); - -#define CMC_EXT_CMC_HASHMULTISET_SETF_SOURCE_(PFX, SNAME, V) \ -\ - struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, NULL); \ -\ - if (!_set_r_) \ - return NULL; \ -\ - struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ - struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter1); CMC_(PFX, _iter_next)(&iter1)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter1); \ -\ - size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter1); \ - size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ - size_t max_ = m1 > m2 ? m1 : m2; \ -\ - CMC_(PFX, _update)(_set_r_, value, max_); \ - } \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter2); CMC_(PFX, _iter_next)(&iter2)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter2); \ -\ - size_t m1 = CMC_(PFX, _impl_multiplicity_of)(_set1_, value); \ - size_t m2 = CMC_(PFX, _iter_multiplicity)(&iter2); \ - size_t max_ = m1 > m2 ? m1 : m2; \ -\ - CMC_(PFX, _update)(_set_r_, value, max_); \ - } \ -\ - CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ -\ - return _set_r_; \ - } \ -\ - struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, NULL); \ -\ - if (!_set_r_) \ - return NULL; \ -\ - struct SNAME *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; \ - struct SNAME *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; \ -\ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_A_); \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ -\ - size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \ - size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set_B_, value); \ - size_t max_ = m1 < m2 ? m1 : m2; \ -\ - CMC_(PFX, _update)(_set_r_, value, max_); \ - } \ -\ - CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ -\ - return _set_r_; \ - } \ -\ - struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, NULL); \ -\ - if (!_set_r_) \ - return NULL; \ -\ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ -\ - size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \ - size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ -\ - if (m1 > m2) \ - CMC_(PFX, _update)(_set_r_, value, m1 - m2); \ - } \ -\ - CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ -\ - return _set_r_; \ - } \ -\ - struct SNAME *CMC_(PFX, _summation)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, NULL); \ -\ - if (!_set_r_) \ - return NULL; \ -\ - struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ - struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter1); CMC_(PFX, _iter_next)(&iter1)) \ - { \ - CMC_(PFX, _insert_many) \ - (_set_r_, CMC_(PFX, _iter_value)(&iter1), CMC_(PFX, _iter_multiplicity)(&iter1)); \ - } \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter2); CMC_(PFX, _iter_next)(&iter2)) \ - { \ - CMC_(PFX, _insert_many) \ - (_set_r_, CMC_(PFX, _iter_value)(&iter2), CMC_(PFX, _iter_multiplicity)(&iter2)); \ - } \ -\ - CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ -\ - return _set_r_; \ - } \ -\ - struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, NULL); \ -\ - if (!_set_r_) \ - return NULL; \ - struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ - struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter1); CMC_(PFX, _iter_next)(&iter1)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter1); \ -\ - size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter1); \ - size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ -\ - if (m1 != m2) \ - { \ - if (m1 > m2) \ - CMC_(PFX, _update)(_set_r_, value, m1 - m2); \ - else \ - CMC_(PFX, _update)(_set_r_, value, m2 - m1); \ - } \ - } \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter2); CMC_(PFX, _iter_next)(&iter2)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter2); \ -\ - size_t m1 = CMC_(PFX, _impl_multiplicity_of)(_set1_, value); \ - size_t m2 = CMC_(PFX, _iter_multiplicity)(&iter2); \ -\ - if (m1 != m2) \ - { \ - if (m1 > m2) \ - CMC_(PFX, _update)(_set_r_, value, m1 - m2); \ - else \ - CMC_(PFX, _update)(_set_r_, value, m2 - m1); \ - } \ - } \ -\ - CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ -\ - return _set_r_; \ - } \ -\ - bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - if (_set1_->count > _set2_->count) \ - return false; \ -\ - if (CMC_(PFX, _empty)(_set1_)) \ - return true; \ -\ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ -\ - size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \ - size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ -\ - if (m1 > m2) \ - return false; \ - } \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - return CMC_(PFX, _is_subset)(_set2_, _set1_); \ - } \ -\ - bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - if (_set1_->count >= _set2_->count) \ - return false; \ -\ - if (CMC_(PFX, _empty)(_set1_)) \ - { \ - if (!CMC_(PFX, _empty)(_set2_)) \ - return true; \ - else \ - return false; \ - } \ -\ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ -\ - size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \ - size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \ -\ - if (m1 >= m2) \ - return false; \ - } \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - return CMC_(PFX, _is_proper_subset)(_set2_, _set1_); \ - } \ -\ - bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - if (CMC_(PFX, _empty)(_set1_)) \ - return true; \ -\ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ -\ - if (CMC_(PFX, _impl_get_entry)(_set2_, value) != NULL) \ - return false; \ - } \ -\ - return true; \ - } - -/** - * STR - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_HASHMULTISET_STR(ACCESS, FILE, PARAMS) \ - CMC_(CMC_(CMC_EXT_CMC_HASHMULTISET_STR_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_HASHMULTISET_STR_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHMULTISET_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHMULTISET_STR_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_HASHMULTISET_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHMULTISET_STR_PRIVATE_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHMULTISET_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHMULTISET_STR_PRIVATE_SOURCE(PARAMS) \ - CMC_EXT_CMC_HASHMULTISET_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHMULTISET_STR_HEADER_(PFX, SNAME, V) \ -\ - bool CMC_(PFX, _to_string)(struct SNAME * _set_, FILE * fptr); \ - bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr, const char *start, const char *separator, \ - const char *end, const char *key_val_sep); - -#define CMC_EXT_CMC_HASHMULTISET_STR_SOURCE_(PFX, SNAME, V) \ -\ - bool CMC_(PFX, _to_string)(struct SNAME * _set_, FILE * fptr) \ - { \ - struct SNAME *s_ = _set_; \ -\ - return 0 <= fprintf(fptr, \ - "struct %s<%s> " \ - "at %p { " \ - "buffer:%p, " \ - "capacity:%" PRIuMAX ", " \ - "count:%" PRIuMAX ", " \ - "cardinality:%" PRIuMAX ", " \ - "load:%lf, " \ - "flag:%d, " \ - "f_val:%p, " \ - "alloc:%p, " \ - "callbacks:%p }", \ - CMC_TO_STRING(SNAME), CMC_TO_STRING(V), s_, s_->buffer, s_->capacity, s_->count, \ - s_->cardinality, s_->load, s_->flag, s_->f_val, s_->alloc, CMC_CALLBACKS_GET(s_)); \ - } \ -\ - bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr, const char *start, const char *separator, \ - const char *end, const char *val_mul_sep) \ - { \ - fprintf(fptr, "%s", start); \ -\ - size_t last = 0; \ - for (size_t i = _set_->capacity; i > 0; i--) \ - { \ - if ((_set_->buffer[i - 1]).state == CMC_ES_FILLED) \ - { \ - last = i - 1; \ - break; \ - } \ - } \ -\ - for (size_t i = 0; i < _set_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \ -\ - if (entry->state == CMC_ES_FILLED) \ - { \ - if (!_set_->f_val->str(fptr, entry->value)) \ - return false; \ -\ - fprintf(fptr, "%s", val_mul_sep); \ -\ - if (fprintf(fptr, "%" PRIuMAX "", entry->multiplicity) < 0) \ - return false; \ -\ - if (i + 1 < last) \ - fprintf(fptr, "%s", separator); \ - } \ - } \ -\ - fprintf(fptr, "%s", end); \ -\ - return true; \ - } - -#endif /* CMC_EXT_CMC_HASHMULTISET_H */ diff --git a/src/ext_cmc_hashset.h b/src/ext_cmc_hashset.h deleted file mode 100644 index 41c5f3f..0000000 --- a/src/ext_cmc_hashset.h +++ /dev/null @@ -1,717 +0,0 @@ -/** - * Copyright (c) 2019 Leonardo Vencovsky - * - * This file is part of the C Macro Collections Libray. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * ext_cmc_hashset.h - * - * Creation Date: 29/05/2020 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -#ifndef CMC_EXT_CMC_HASHSET_H -#define CMC_EXT_CMC_HASHSET_H - -#include "cor_core.h" - -/** - * All the EXT parts of CMC HashSet. - */ -#define CMC_EXT_CMC_HASHSET_PARTS ITER, SETF, STR - -/** - * ITER - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_HASHSET_ITER(ACCESS, FILE, PARAMS) \ - CMC_(CMC_(CMC_EXT_CMC_HASHSET_ITER_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_HASHSET_ITER_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHSET_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHSET_ITER_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_HASHSET_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHSET_ITER_PRIVATE_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHSET_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHSET_ITER_PRIVATE_SOURCE(PARAMS) \ - CMC_EXT_CMC_HASHSET_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHSET_ITER_HEADER_(PFX, SNAME, V) \ -\ - /* HashSet Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target HashSet */ \ - struct SNAME *target; \ -\ - /* Cursor's position (index) */ \ - size_t cursor; \ -\ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ -\ - /* The index of the first element */ \ - size_t first; \ -\ - /* The index of the last element */ \ - size_t last; \ -\ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ -\ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ -\ - /* Iterator Initialization */ \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ - /* Iterator Access */ \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); - -#define CMC_EXT_CMC_HASHSET_ITER_SOURCE_(PFX, SNAME, V) \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.cursor = 0; \ - iter.index = 0; \ - iter.first = 0; \ - iter.last = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ -\ - if (!CMC_(PFX, _empty)(target)) \ - { \ - for (size_t i = 0; i < target->capacity; i++) \ - { \ - if (target->buffer[i].state == CMC_ES_FILLED) \ - { \ - iter.first = i; \ - break; \ - } \ - } \ -\ - iter.cursor = iter.first; \ -\ - for (size_t i = target->capacity; i > 0; i--) \ - { \ - if (target->buffer[i - 1].state == CMC_ES_FILLED) \ - { \ - iter.last = i - 1; \ - break; \ - } \ - } \ - } \ -\ - return iter; \ - } \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.cursor = 0; \ - iter.index = 0; \ - iter.first = 0; \ - iter.last = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ -\ - if (!CMC_(PFX, _empty)(target)) \ - { \ - for (size_t i = 0; i < target->capacity; i++) \ - { \ - if (target->buffer[i].state == CMC_ES_FILLED) \ - { \ - iter.first = i; \ - break; \ - } \ - } \ -\ - for (size_t i = target->capacity; i > 0; i--) \ - { \ - if (target->buffer[i - 1].state == CMC_ES_FILLED) \ - { \ - iter.last = i - 1; \ - break; \ - } \ - } \ -\ - iter.cursor = iter.last; \ - iter.index = target->count - 1; \ - } \ -\ - return iter; \ - } \ -\ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ -\ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ -\ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->first; \ - iter->index = 0; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->last; \ - iter->index = iter->target->count - 1; \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->end = true; \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - iter->start = CMC_(PFX, _empty)(iter->target); \ -\ - struct CMC_DEF_ENTRY(SNAME) *scan = &(iter->target->buffer[iter->cursor]); \ -\ - iter->index++; \ -\ - while (1) \ - { \ - iter->cursor++; \ - scan = &(iter->target->buffer[iter->cursor]); \ -\ - if (scan->state == CMC_ES_FILLED) \ - break; \ - } \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - struct CMC_DEF_ENTRY(SNAME) *scan = &(iter->target->buffer[iter->cursor]); \ -\ - iter->index--; \ -\ - while (1) \ - { \ - iter->cursor--; \ - scan = &(iter->target->buffer[iter->cursor]); \ -\ - if (scan->state == CMC_ES_FILLED) \ - break; \ - } \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->index + steps >= iter->target->count) \ - return false; \ -\ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_next)(iter); \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->index < steps) \ - return false; \ -\ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_prev)(iter); \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ -\ - if (iter->index > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ - else if (iter->index < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ -\ - return true; \ - } \ -\ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ -\ - return iter->target->buffer[iter->cursor].value; \ - } \ -\ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->index; \ - } - -/** - * SETF - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_HASHSET_SETF(ACCESS, FILE, PARAMS) \ - CMC_(CMC_(CMC_EXT_CMC_HASHSET_SETF_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_HASHSET_SETF_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHSET_SETF_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHSET_SETF_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_HASHSET_SETF_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHSET_SETF_PRIVATE_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHSET_SETF_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHSET_SETF_PRIVATE_SOURCE(PARAMS) \ - CMC_EXT_CMC_HASHSET_SETF_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHSET_SETF_HEADER_(PFX, SNAME, V) \ -\ - /* Set Operations */ \ - struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, struct SNAME * _set2_); \ - bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_); \ - bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, struct SNAME * _set2_); \ - bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, struct SNAME * _set2_); \ - bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, struct SNAME * _set2_); \ - bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, struct SNAME * _set2_); - -#define CMC_EXT_CMC_HASHSET_SETF_SOURCE_(PFX, SNAME, V) \ -\ - struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, NULL); \ -\ - if (!_set_r_) \ - { \ - _set1_->flag = CMC_FLAG_ALLOC; \ - _set2_->flag = CMC_FLAG_ALLOC; \ - return NULL; \ - } \ -\ - struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ - struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ -\ - /* TODO turn this into a normal loop and check for errors */ \ - for (; !CMC_(PFX, _iter_at_end)(&iter1); CMC_(PFX, _iter_next)(&iter1)) \ - { \ - CMC_(PFX, _insert)(_set_r_, CMC_(PFX, _iter_value)(&iter1)); \ - } \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter2); CMC_(PFX, _iter_next)(&iter2)) \ - { \ - CMC_(PFX, _insert)(_set_r_, CMC_(PFX, _iter_value)(&iter2)); \ - } \ -\ - CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ -\ - return _set_r_; \ - } \ -\ - struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, NULL); \ -\ - if (!_set_r_) \ - { \ - _set1_->flag = CMC_FLAG_ALLOC; \ - _set2_->flag = CMC_FLAG_ALLOC; \ - return NULL; \ - } \ -\ - struct SNAME *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; \ - struct SNAME *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; \ -\ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_A_); \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ -\ - if (CMC_(PFX, _impl_get_entry)(_set_B_, value) != NULL) \ - CMC_(PFX, _insert)(_set_r_, value); \ - } \ -\ - CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ -\ - return _set_r_; \ - } \ -\ - struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, NULL); \ -\ - if (!_set_r_) \ - { \ - _set1_->flag = CMC_FLAG_ALLOC; \ - _set2_->flag = CMC_FLAG_ALLOC; \ - return NULL; \ - } \ -\ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ -\ - if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \ - CMC_(PFX, _insert)(_set_r_, value); \ - } \ -\ - CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ -\ - return _set_r_; \ - } \ -\ - struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - /* Callbacks are added later */ \ - struct SNAME *_set_r_ = \ - CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, NULL); \ -\ - if (!_set_r_) \ - { \ - _set1_->flag = CMC_FLAG_ALLOC; \ - _set2_->flag = CMC_FLAG_ALLOC; \ - return NULL; \ - } \ -\ - struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ - struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter1); CMC_(PFX, _iter_next)(&iter1)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter1); \ -\ - if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \ - CMC_(PFX, _insert)(_set_r_, value); \ - } \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter2); CMC_(PFX, _iter_next)(&iter2)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter2); \ -\ - if (CMC_(PFX, _impl_get_entry)(_set1_, value) == NULL) \ - CMC_(PFX, _insert)(_set_r_, value); \ - } \ -\ - CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ -\ - return _set_r_; \ - } \ -\ - /* Is _set1_ a subset of _set2_ ? */ \ - /* A set X is a subset of a set Y when: X <= Y */ \ - /* If X is a subset of Y, then Y is a superset of X */ \ - bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - _set1_->flag = CMC_FLAG_OK; \ - _set2_->flag = CMC_FLAG_OK; \ -\ - /* If the cardinality of _set1_ is greater than that of _set2_, */ \ - /* then it is safe to say that _set1_ can't be a subset of _set2_ */ \ - if (_set1_->count > _set2_->count) \ - return false; \ -\ - /* The empty set is a subset of all sets */ \ - if (CMC_(PFX, _empty)(_set1_)) \ - return true; \ -\ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ -\ - if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \ - return false; \ - } \ -\ - return true; \ - } \ -\ - /* Is _set1_ a superset of _set2_ ? */ \ - /* A set X is a superset of a set Y when: X >= Y */ \ - /* If X is a superset of Y, then Y is a subset of X */ \ - bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - return CMC_(PFX, _is_subset)(_set2_, _set1_); \ - } \ -\ - /* Is _set1_ a proper subset of _set2_ ? */ \ - /* A set X is a proper subset of a set Y when: X < Y */ \ - /* If X is a proper subset of Y, then Y is a proper superset of X */ \ - bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - _set1_->flag = CMC_FLAG_OK; \ - _set2_->flag = CMC_FLAG_OK; \ -\ - /* If the cardinality of _set1_ is greater than or equal to that of */ \ - /* _set2_, then it is safe to say that _set1_ can't be a proper */ \ - /* subset of _set2_ */ \ - if (_set1_->count >= _set2_->count) \ - return false; \ -\ - if (CMC_(PFX, _empty)(_set1_)) \ - { \ - /* The empty set is a proper subset of all non-empty sets */ \ - if (!CMC_(PFX, _empty)(_set2_)) \ - return true; \ - /* The empty set is not a proper subset of itself (this is true */ \ - /* for any set) */ \ - else \ - return false; \ - } \ -\ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ -\ - if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \ - return false; \ - } \ -\ - return true; \ - } \ -\ - /* Is _set1_ a proper superset of _set2_ ? */ \ - /* A set X is a proper superset of a set Y when: X > Y */ \ - /* If X is a proper superset of Y, then Y is a proper subset of X */ \ - bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - return CMC_(PFX, _is_proper_subset)(_set2_, _set1_); \ - } \ -\ - /* Is _set1_ a disjointset of _set2_ ? */ \ - /* A set X is a disjointset of a set Y if their intersection is empty, */ \ - /* that is, if there are no elements in common between the two */ \ - bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - _set1_->flag = CMC_FLAG_OK; \ - _set2_->flag = CMC_FLAG_OK; \ -\ - /* The intersection of an empty set with any other set will result */ \ - /* in an empty set */ \ - if (CMC_(PFX, _empty)(_set1_)) \ - return true; \ -\ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ -\ - if (CMC_(PFX, _impl_get_entry)(_set2_, value) != NULL) \ - return false; \ - } \ -\ - return true; \ - } - -/** - * STR - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_HASHSET_STR(ACCESS, FILE, PARAMS) \ - CMC_(CMC_(CMC_EXT_CMC_HASHSET_STR_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_HASHSET_STR_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHSET_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHSET_STR_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_HASHSET_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHSET_STR_PRIVATE_HEADER(PARAMS) \ - CMC_EXT_CMC_HASHSET_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHSET_STR_PRIVATE_SOURCE(PARAMS) \ - CMC_EXT_CMC_HASHSET_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HASHSET_STR_HEADER_(PFX, SNAME, V) \ -\ - bool CMC_(PFX, _to_string)(struct SNAME * _set_, FILE * fptr); \ - bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr, const char *start, const char *separator, \ - const char *end); - -#define CMC_EXT_CMC_HASHSET_STR_SOURCE_(PFX, SNAME, V) \ -\ - bool CMC_(PFX, _to_string)(struct SNAME * _set_, FILE * fptr) \ - { \ - struct SNAME *s_ = _set_; \ -\ - return 0 <= fprintf(fptr, \ - "struct %s<%s> " \ - "at %p { " \ - "buffer:%p, " \ - "capacity:%" PRIuMAX ", " \ - "count:%" PRIuMAX ", " \ - "load:%lf, " \ - "flag:%d, " \ - "f_val:%p, " \ - "alloc:%p, " \ - "callbacks: %p }", \ - CMC_TO_STRING(SNAME), CMC_TO_STRING(V), s_, s_->buffer, s_->capacity, s_->count, s_->load, \ - s_->flag, s_->f_val, s_->alloc, CMC_CALLBACKS_GET(s_)); \ - } \ -\ - bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr, const char *start, const char *separator, \ - const char *end) \ - { \ - fprintf(fptr, "%s", start); \ -\ - size_t last = 0; \ - for (size_t i = _set_->capacity; i > 0; i--) \ - { \ - if ((_set_->buffer[i - 1]).state == CMC_ES_FILLED) \ - { \ - last = i - 1; \ - break; \ - } \ - } \ -\ - for (size_t i = 0; i < _set_->capacity; i++) \ - { \ - struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \ -\ - if (entry->state == CMC_ES_FILLED) \ - { \ - if (!_set_->f_val->str(fptr, entry->value)) \ - return false; \ -\ - if (i + 1 < last) \ - fprintf(fptr, "%s", separator); \ - } \ - } \ -\ - fprintf(fptr, "%s", end); \ -\ - return true; \ - } - -#endif /* CMC_EXT_CMC_HASHSET_H */ diff --git a/src/ext_cmc_heap.h b/src/ext_cmc_heap.h deleted file mode 100644 index 578b2c1..0000000 --- a/src/ext_cmc_heap.h +++ /dev/null @@ -1,348 +0,0 @@ -/** - * Copyright (c) 2019 Leonardo Vencovsky - * - * This file is part of the C Macro Collections Libray. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * ext_cmc_heap.h - * - * Creation Date: 01/06/2020 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -#ifndef CMC_EXT_CMC_HEAP_H -#define CMC_EXT_CMC_HEAP_H - -#include "cor_core.h" - -/** - * All the EXT parts of CMC Heap. - */ -#define CMC_EXT_CMC_HEAP_PARTS ITER, STR - -/** - * ITER - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_HEAP_ITER(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_EXT_CMC_HEAP_ITER_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_HEAP_ITER_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_HEAP_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HEAP_ITER_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_HEAP_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HEAP_ITER_PRIVATE_HEADER(PARAMS) \ - CMC_EXT_CMC_HEAP_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HEAP_ITER_PRIVATE_SOURCE(PARAMS) \ - CMC_EXT_CMC_HEAP_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HEAP_ITER_HEADER_(PFX, SNAME, V) \ -\ - /* Heap Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target heap */ \ - struct SNAME *target; \ -\ - /* Cursor's position (index) */ \ - size_t cursor; \ -\ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ -\ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ -\ - /* Iterator Initialization */ \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ - /* Iterator Access */ \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); - -#define CMC_EXT_CMC_HEAP_ITER_SOURCE_(PFX, SNAME, V) \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.cursor = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ -\ - return iter; \ - } \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.cursor = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ -\ - if (!CMC_(PFX, _empty)(target)) \ - iter.cursor = target->count - 1; \ -\ - return iter; \ - } \ -\ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ -\ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ -\ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = 0; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->target->count - 1; \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->end = true; \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->cursor + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - iter->start = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor++; \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->cursor == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor--; \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->cursor + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->cursor + steps >= iter->target->count) \ - return false; \ -\ - if (iter->end) \ - return false; \ -\ - iter->start = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor += steps; \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->cursor == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->cursor < steps) \ - return false; \ -\ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor -= steps; \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ -\ - if (iter->cursor > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->cursor - index); \ - else if (iter->cursor < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->cursor); \ -\ - return true; \ - } \ -\ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ -\ - return iter->target->buffer[iter->cursor]; \ - } \ -\ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->cursor; \ - } - -/** - * STR - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_HEAP_STR(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_EXT_CMC_HEAP_STR_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_HEAP_STR_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_HEAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HEAP_STR_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_HEAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HEAP_STR_PRIVATE_HEADER(PARAMS) \ - CMC_EXT_CMC_HEAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HEAP_STR_PRIVATE_SOURCE(PARAMS) \ - CMC_EXT_CMC_HEAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_HEAP_STR_HEADER_(PFX, SNAME, V) \ -\ - bool CMC_(PFX, _to_string)(struct SNAME * _heap_, FILE * fptr); \ - bool CMC_(PFX, _print)(struct SNAME * _heap_, FILE * fptr, const char *start, const char *separator, \ - const char *end); - -#define CMC_EXT_CMC_HEAP_STR_SOURCE_(PFX, SNAME, V) \ -\ - bool CMC_(PFX, _to_string)(struct SNAME * _heap_, FILE * fptr) \ - { \ - struct SNAME *h_ = _heap_; \ - const char *t = h_->HO == 1 ? "MaxHeap" : "MinHeap"; \ -\ - return 0 <= fprintf(fptr, \ - "struct %s<%s> " \ - "at %p { " \ - "buffer:%p, " \ - "capacity:%" PRIuMAX ", " \ - "count:%" PRIuMAX ", " \ - "type:%s, " \ - "flag:%d, " \ - "f_val:%p, " \ - "alloc:%p, " \ - "callbacks: %p}", \ - CMC_TO_STRING(SNAME), CMC_TO_STRING(V), h_, h_->buffer, h_->capacity, h_->count, t, \ - h_->flag, h_->f_val, h_->alloc, CMC_CALLBACKS_GET(h_)); \ - } \ -\ - bool CMC_(PFX, _print)(struct SNAME * _heap_, FILE * fptr, const char *start, const char *separator, \ - const char *end) \ - { \ - fprintf(fptr, "%s", start); \ -\ - for (size_t i = 0; i < _heap_->count; i++) \ - { \ - if (!_heap_->f_val->str(fptr, _heap_->buffer[i])) \ - return false; \ -\ - if (i + 1 < _heap_->count) \ - fprintf(fptr, "%s", separator); \ - } \ -\ - fprintf(fptr, "%s", end); \ -\ - return true; \ - } - -#endif /* CMC_EXT_CMC_HEAP_H */ diff --git a/src/ext_cmc_intervalheap.h b/src/ext_cmc_intervalheap.h deleted file mode 100644 index f75ef7c..0000000 --- a/src/ext_cmc_intervalheap.h +++ /dev/null @@ -1,349 +0,0 @@ -/** - * Copyright (c) 2019 Leonardo Vencovsky - * - * This file is part of the C Macro Collections Libray. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * ext_cmc_intervalheap.h - * - * Creation Date: 02/06/2020 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -#ifndef CMC_EXT_CMC_INTERVALHEAP_H -#define CMC_EXT_CMC_INTERVALHEAP_H - -#include "cor_core.h" - -/** - * All the EXT parts of CMC IntervalHeap. - */ -#define CMC_EXT_CMC_INTERVALHEAP_PARTS ITER, STR - -/** - * ITER - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_INTERVALHEAP_ITER(ACCESS, FILE, PARAMS) \ - CMC_(CMC_(CMC_EXT_CMC_INTERVALHEAP_ITER_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_INTERVALHEAP_ITER_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_INTERVALHEAP_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_INTERVALHEAP_ITER_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_INTERVALHEAP_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_INTERVALHEAP_ITER_PRIVATE_HEADER(PARAMS) \ - CMC_EXT_CMC_INTERVALHEAP_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_INTERVALHEAP_ITER_PRIVATE_SOURCE(PARAMS) \ - CMC_EXT_CMC_INTERVALHEAP_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_INTERVALHEAP_ITER_HEADER_(PFX, SNAME, V) \ -\ - /* IntervalHeap Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target IntervalHeap */ \ - struct SNAME *target; \ -\ - /* Cursor's position (index) */ \ - size_t cursor; \ -\ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ -\ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ -\ - /* Iterator Initialization */ \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ - /* Iterator Access */ \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); - -#define CMC_EXT_CMC_INTERVALHEAP_ITER_SOURCE_(PFX, SNAME, V) \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.cursor = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ -\ - return iter; \ - } \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.cursor = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ -\ - if (!CMC_(PFX, _empty)(target)) \ - iter.cursor = target->count - 1; \ -\ - return iter; \ - } \ -\ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ -\ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ -\ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = 0; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->target->count - 1; \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->end = true; \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->cursor + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - iter->start = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor++; \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->cursor == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor--; \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->cursor + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->cursor + steps >= iter->target->count) \ - return false; \ -\ - if (iter->end) \ - return false; \ -\ - iter->start = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor += steps; \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->cursor == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->cursor < steps) \ - return false; \ -\ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor -= steps; \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ -\ - if (iter->cursor > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->cursor - index); \ - else if (iter->cursor < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->cursor); \ -\ - return true; \ - } \ -\ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ -\ - return iter->target->buffer[iter->cursor / 2][iter->cursor % 2]; \ - } \ -\ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->cursor; \ - } - -/** - * STR - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_INTERVALHEAP_STR(ACCESS, FILE, PARAMS) \ - CMC_(CMC_(CMC_EXT_CMC_INTERVALHEAP_STR_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_INTERVALHEAP_STR_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_INTERVALHEAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_INTERVALHEAP_STR_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_INTERVALHEAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_INTERVALHEAP_STR_PRIVATE_HEADER(PARAMS) \ - CMC_EXT_CMC_INTERVALHEAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_INTERVALHEAP_STR_PRIVATE_SOURCE(PARAMS) \ - CMC_EXT_CMC_INTERVALHEAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_INTERVALHEAP_STR_HEADER_(PFX, SNAME, V) \ -\ - bool CMC_(PFX, _to_string)(struct SNAME * _heap_, FILE * fptr); \ - bool CMC_(PFX, _print)(struct SNAME * _heap_, FILE * fptr, const char *start, const char *separator, \ - const char *end); - -#define CMC_EXT_CMC_INTERVALHEAP_STR_SOURCE_(PFX, SNAME, V) \ -\ - bool CMC_(PFX, _to_string)(struct SNAME * _heap_, FILE * fptr) \ - { \ - struct SNAME *h_ = _heap_; \ -\ - return 0 <= fprintf(fptr, \ - "struct %s<%s> " \ - "at %p { " \ - "buffer:%p, " \ - "capacity:%" PRIuMAX ", " \ - "size:%" PRIuMAX ", " \ - "count:%" PRIuMAX ", " \ - "flag:%d, " \ - "f_val:%p, " \ - "alloc:%p, " \ - "callbacks:%p }", \ - CMC_TO_STRING(SNAME), CMC_TO_STRING(V), h_, h_->buffer, h_->capacity, h_->size, h_->count, \ - h_->flag, h_->f_val, h_->alloc, CMC_CALLBACKS_GET(h_)); \ - } \ -\ - bool CMC_(PFX, _print)(struct SNAME * _heap_, FILE * fptr, const char *start, const char *separator, \ - const char *end) \ - { \ - fprintf(fptr, "%s", start); \ -\ - for (size_t i = 0; i < _heap_->count; i++) \ - { \ - if (!_heap_->f_val->str(fptr, _heap_->buffer[i / 2][i % 2])) \ - return false; \ -\ - if (i + 1 < _heap_->count) \ - fprintf(fptr, "%s", separator); \ - } \ -\ - fprintf(fptr, "%s", end); \ -\ - return true; \ - } - -#endif /* CMC_EXT_CMC_INTERVALHEAP_H */ diff --git a/src/ext_cmc_linkedlist.h b/src/ext_cmc_linkedlist.h deleted file mode 100644 index 40001b6..0000000 --- a/src/ext_cmc_linkedlist.h +++ /dev/null @@ -1,618 +0,0 @@ -/** - * Copyright (c) 2019 Leonardo Vencovsky - * - * This file is part of the C Macro Collections Libray. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * ext_cmc_linkedlist.h - * - * Creation Date: 03/06/2020 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -#ifndef CMC_EXT_CMC_LINKEDLIST_H -#define CMC_EXT_CMC_LINKEDLIST_H - -#include "cor_core.h" - -/** - * All the EXT parts of CMC LinkedList. - */ -#define CMC_EXT_CMC_LINKEDLIST_PARTS ITER, NODE, STR - -/** - * ITER - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_LINKEDLIST_ITER(ACCESS, FILE, PARAMS) \ - CMC_(CMC_(CMC_EXT_CMC_LINKEDLIST_ITER_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_LINKEDLIST_ITER_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_LINKEDLIST_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_LINKEDLIST_ITER_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_LINKEDLIST_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_LINKEDLIST_ITER_PRIVATE_HEADER(PARAMS) \ - CMC_EXT_CMC_LINKEDLIST_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_LINKEDLIST_ITER_PRIVATE_SOURCE(PARAMS) \ - CMC_EXT_CMC_LINKEDLIST_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_LINKEDLIST_ITER_HEADER_(PFX, SNAME, V) \ -\ - /* LinkedList Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target Linked List */ \ - struct SNAME *target; \ -\ - /* Cursor's current node */ \ - struct CMC_DEF_NODE(SNAME) * cursor; \ -\ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ -\ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ -\ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ -\ - /* Iterator Initialization */ \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ - /* Iterator Access */ \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); \ - struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _iter_node)(struct CMC_DEF_ITER(SNAME) * iter); - -#define CMC_EXT_CMC_LINKEDLIST_ITER_SOURCE_(PFX, SNAME, V) \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.cursor = target->head; \ - iter.index = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ -\ - return iter; \ - } \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.cursor = target->tail; \ - iter.index = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ -\ - if (!CMC_(PFX, _empty)(target)) \ - iter.index = target->count - 1; \ -\ - return iter; \ - } \ -\ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ -\ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ -\ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->target->head; \ - iter->index = 0; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->target->tail; \ - iter->index = iter->target->count - 1; \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->end = true; \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->cursor->next == NULL) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - iter->start = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor = iter->cursor->next; \ - iter->index++; \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->cursor->prev == NULL) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor = iter->cursor->prev; \ - iter->index--; \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->cursor->next == NULL) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->index + steps >= iter->target->count) \ - return false; \ -\ - iter->start = CMC_(PFX, _empty)(iter->target); \ -\ - iter->index += steps; \ -\ - for (size_t i = 0; i < steps; i++) \ - iter->cursor = iter->cursor->next; \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->cursor->prev == NULL) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->index < steps) \ - return false; \ -\ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - iter->index -= steps; \ -\ - for (size_t i = 0; i < steps; i++) \ - iter->cursor = iter->cursor->prev; \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ -\ - if (iter->index > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ - else if (iter->index < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ -\ - return true; \ - } \ -\ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ -\ - return iter->cursor->value; \ - } \ -\ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return NULL; \ -\ - return &(iter->cursor->value); \ - } \ -\ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->index; \ - } \ -\ - struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _iter_node)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->cursor; \ - } - -/** - * NODE - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_LINKEDLIST_NODE(ACCESS, FILE, PARAMS) \ - CMC_(CMC_(CMC_EXT_CMC_LINKEDLIST_NODE_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_LINKEDLIST_NODE_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_LINKEDLIST_NODE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_LINKEDLIST_NODE_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_LINKEDLIST_NODE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_LINKEDLIST_NODE_PRIVATE_HEADER(PARAMS) \ - CMC_EXT_CMC_LINKEDLIST_NODE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_LINKEDLIST_NODE_PRIVATE_SOURCE(PARAMS) \ - CMC_EXT_CMC_LINKEDLIST_NODE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_LINKEDLIST_NODE_HEADER_(PFX, SNAME, V) \ -\ - /* Node Allocation and Deallocation */ \ - struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _new_node)(struct SNAME * _list_, V value); \ - void CMC_(PFX, _free_node)(struct SNAME * _list_, struct CMC_DEF_NODE(SNAME) * _node_); \ - /* Node Access Relative to a Linked List */ \ - struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _head)(struct SNAME * _list_); \ - struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _get_node)(struct SNAME * _list_, size_t index); \ - struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _tail)(struct SNAME * _list_); \ - /* Input and Output Relative to a Node */ \ - bool CMC_(PFX, _add_next)(struct SNAME * _owner_, struct CMC_DEF_NODE(SNAME) * _node_, V value); \ - bool CMC_(PFX, _add_prev)(struct SNAME * _owner_, struct CMC_DEF_NODE(SNAME) * _node_, V value); \ - bool CMC_(PFX, _del_next)(struct SNAME * _owner_, struct CMC_DEF_NODE(SNAME) * _node_); \ - bool CMC_(PFX, _del_curr)(struct SNAME * _owner_, struct CMC_DEF_NODE(SNAME) * _node_); \ - bool CMC_(PFX, _del_prev)(struct SNAME * _owner_, struct CMC_DEF_NODE(SNAME) * _node_); \ - /* Node Access Relative to a Linked List Node */ \ - struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _next_node)(struct CMC_DEF_NODE(SNAME) * _node_); \ - struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _prev_node)(struct CMC_DEF_NODE(SNAME) * _node_); - -#define CMC_EXT_CMC_LINKEDLIST_NODE_SOURCE_(PFX, SNAME, V) \ -\ - struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _new_node)(struct SNAME * _list_, V value) \ - { \ - struct CMC_DEF_NODE(SNAME) *_node_ = _list_->alloc->malloc(sizeof(struct CMC_DEF_NODE(SNAME))); \ -\ - if (!_node_) \ - { \ - _list_->flag = CMC_FLAG_ALLOC; \ - return NULL; \ - } \ -\ - _node_->value = value; \ - _node_->next = NULL; \ - _node_->prev = NULL; \ -\ - return _node_; \ - } \ -\ - void CMC_(PFX, _free_node)(struct SNAME * _list_, struct CMC_DEF_NODE(SNAME) * _node_) \ - { \ - _list_->alloc->free(_node_); \ - } \ -\ - struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _head)(struct SNAME * _list_) \ - { \ - return _list_->head; \ - } \ -\ - struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _get_node)(struct SNAME * _list_, size_t index) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return NULL; \ - } \ -\ - if (index >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return NULL; \ - } \ -\ - struct CMC_DEF_NODE(SNAME) *_node_ = NULL; \ -\ - if (index <= _list_->count / 2) \ - { \ - _node_ = _list_->head; \ - for (size_t i = 0; i < index; i++) \ - { \ - _node_ = _node_->next; \ - } \ - } \ - else \ - { \ - _node_ = _list_->tail; \ - for (size_t i = _list_->count - 1; i > index; i--) \ - { \ - _node_ = _node_->prev; \ - } \ - } \ -\ - _list_->flag = CMC_FLAG_OK; \ -\ - return _node_; \ - } \ -\ - struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _tail)(struct SNAME * _list_) \ - { \ - return _list_->tail; \ - } \ -\ - bool CMC_(PFX, _add_next)(struct SNAME * _owner_, struct CMC_DEF_NODE(SNAME) * _node_, V value) \ - { \ - struct CMC_DEF_NODE(SNAME) *new_node = CMC_(PFX, _new_node)(_owner_, value); \ -\ - if (!new_node) \ - return false; \ -\ - new_node->next = _node_->next; \ -\ - if (_node_->next != NULL) \ - _node_->next->prev = new_node; \ - else \ - _owner_->tail = new_node; \ -\ - new_node->prev = _node_; \ - _node_->next = new_node; \ -\ - _owner_->count++; \ - _owner_->flag = CMC_FLAG_OK; \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _add_prev)(struct SNAME * _owner_, struct CMC_DEF_NODE(SNAME) * _node_, V value) \ - { \ - struct CMC_DEF_NODE(SNAME) *new_node = CMC_(PFX, _new_node)(_owner_, value); \ -\ - if (!new_node) \ - return false; \ -\ - new_node->prev = _node_->prev; \ -\ - if (_node_->prev != NULL) \ - _node_->prev->next = new_node; \ - else \ - _owner_->head = new_node; \ -\ - new_node->next = _node_; \ - _node_->prev = new_node; \ -\ - _owner_->count++; \ - _owner_->flag = CMC_FLAG_OK; \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _del_next)(struct SNAME * _owner_, struct CMC_DEF_NODE(SNAME) * _node_) \ - { \ - if (_node_->next == NULL) \ - { \ - _owner_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ -\ - struct CMC_DEF_NODE(SNAME) *tmp = _node_->next; \ -\ - _node_->next = _node_->next->next; \ -\ - if (tmp->next != NULL) \ - tmp->next->prev = _node_; \ - else \ - _owner_->tail = _node_; \ -\ - _owner_->alloc->free(tmp); \ -\ - _owner_->count--; \ - _owner_->flag = CMC_FLAG_OK; \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _del_curr)(struct SNAME * _owner_, struct CMC_DEF_NODE(SNAME) * _node_) \ - { \ - if (_node_->prev != NULL) \ - _node_->prev->next = _node_->next; \ - else \ - _owner_->head = _node_->next; \ -\ - if (_node_->next != NULL) \ - _node_->next->prev = _node_->prev; \ - else \ - _owner_->tail = _node_->prev; \ -\ - _owner_->alloc->free(_node_); \ -\ - _owner_->count--; \ - _owner_->flag = CMC_FLAG_OK; \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _del_prev)(struct SNAME * _owner_, struct CMC_DEF_NODE(SNAME) * _node_) \ - { \ - if (_node_->prev == NULL) \ - { \ - _owner_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ -\ - struct CMC_DEF_NODE(SNAME) *tmp = _node_->prev; \ -\ - _node_->prev = _node_->prev->prev; \ -\ - if (tmp->prev != NULL) \ - tmp->prev->next = _node_; \ - else \ - _owner_->head = _node_; \ -\ - _owner_->alloc->free(tmp); \ -\ - _owner_->count--; \ - _owner_->flag = CMC_FLAG_OK; \ -\ - return true; \ - } \ -\ - struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _next_node)(struct CMC_DEF_NODE(SNAME) * _node_) \ - { \ - return _node_->next; \ - } \ -\ - struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _prev_node)(struct CMC_DEF_NODE(SNAME) * _node_) \ - { \ - return _node_->prev; \ - } - -/** - * STR - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_LINKEDLIST_STR(ACCESS, FILE, PARAMS) \ - CMC_(CMC_(CMC_EXT_CMC_LINKEDLIST_STR_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_LINKEDLIST_STR_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_LINKEDLIST_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_LINKEDLIST_STR_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_LINKEDLIST_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_LINKEDLIST_STR_PRIVATE_HEADER(PARAMS) \ - CMC_EXT_CMC_LINKEDLIST_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_LINKEDLIST_STR_PRIVATE_SOURCE(PARAMS) \ - CMC_EXT_CMC_LINKEDLIST_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_LINKEDLIST_STR_HEADER_(PFX, SNAME, V) \ -\ - bool CMC_(PFX, _to_string)(struct SNAME * _list_, FILE * fptr); \ - bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr, const char *start, const char *separator, \ - const char *end); - -#define CMC_EXT_CMC_LINKEDLIST_STR_SOURCE_(PFX, SNAME, V) \ -\ - bool CMC_(PFX, _to_string)(struct SNAME * _list_, FILE * fptr) \ - { \ - struct SNAME *l_ = _list_; \ -\ - return 0 <= fprintf(fptr, \ - "struct %s<%s> " \ - "at %p { " \ - "count:%" PRIuMAX ", " \ - "head:%p, " \ - "tail:%p, " \ - "flag:%d, " \ - "f_val:%p, " \ - "alloc:%p, " \ - "callbacks:%p }", \ - CMC_TO_STRING(SNAME), CMC_TO_STRING(V), l_, l_->count, l_->head, l_->tail, l_->flag, \ - l_->f_val, l_->alloc, CMC_CALLBACKS_GET(l_)); \ - } \ -\ - bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr, const char *start, const char *separator, \ - const char *end) \ - { \ - fprintf(fptr, "%s", start); \ -\ - struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \ -\ - while (scan != NULL) \ - { \ - if (!_list_->f_val->str(fptr, scan->value)) \ - return false; \ -\ - scan = scan->next; \ -\ - if (scan) \ - fprintf(fptr, "%s", separator); \ - } \ -\ - fprintf(fptr, "%s", end); \ -\ - return true; \ - } - -#endif /* CMC_EXT_CMC_LINKEDLIST_H */ diff --git a/src/ext_cmc_list.h b/src/ext_cmc_list.h deleted file mode 100644 index 6e683c3..0000000 --- a/src/ext_cmc_list.h +++ /dev/null @@ -1,540 +0,0 @@ -/** - * Copyright (c) 2019 Leonardo Vencovsky - * - * This file is part of the C Macro Collections Libray. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * ext_cmc_list.h - * - * Creation Date: 04/06/2020 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -#ifndef CMC_EXT_CMC_LIST_H -#define CMC_EXT_CMC_LIST_H - -#include "cor_core.h" - -/** - * All the EXT parts of CMC List. - */ -#define CMC_EXT_CMC_LIST_PARTS ITER, SEQ, STR - -/** - * ITER - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_LIST_ITER(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_EXT_CMC_LIST_ITER_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_LIST_ITER_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_LIST_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_LIST_ITER_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_LIST_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_LIST_ITER_PRIVATE_HEADER(PARAMS) \ - CMC_EXT_CMC_LIST_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_LIST_ITER_PRIVATE_SOURCE(PARAMS) \ - CMC_EXT_CMC_LIST_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_LIST_ITER_HEADER_(PFX, SNAME, V) \ -\ - /* List Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target List */ \ - struct SNAME *target; \ -\ - /* Cursor's position (index) */ \ - size_t cursor; \ -\ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ -\ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ -\ - /* Iterator Initialization */ \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ - /* Iterator Access */ \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); - -#define CMC_EXT_CMC_LIST_ITER_SOURCE_(PFX, SNAME, V) \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.cursor = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ -\ - return iter; \ - } \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.cursor = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ -\ - if (!CMC_(PFX, _empty)(target)) \ - iter.cursor = target->count - 1; \ -\ - return iter; \ - } \ -\ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ -\ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ -\ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = 0; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->cursor = iter->target->count - 1; \ - iter->end = true; \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->cursor + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - iter->start = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor++; \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->cursor == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor--; \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->cursor + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->cursor + steps >= iter->target->count) \ - return false; \ -\ - iter->start = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor += steps; \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->cursor == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->cursor < steps) \ - return false; \ -\ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor -= steps; \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ -\ - if (iter->cursor > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->cursor - index); \ - else if (iter->cursor < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->cursor); \ -\ - return true; \ - } \ -\ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ -\ - return iter->target->buffer[iter->cursor]; \ - } \ -\ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return NULL; \ -\ - return &(iter->target->buffer[iter->cursor]); \ - } \ -\ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->cursor; \ - } - -/** - * SEQ - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_LIST_SEQ(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_EXT_CMC_LIST_SEQ_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_LIST_SEQ_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_LIST_SEQ_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_LIST_SEQ_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_LIST_SEQ_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_LIST_SEQ_PRIVATE_HEADER(PARAMS) \ - CMC_EXT_CMC_LIST_SEQ_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_LIST_SEQ_PRIVATE_SOURCE(PARAMS) \ - CMC_EXT_CMC_LIST_SEQ_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_LIST_SEQ_HEADER_(PFX, SNAME, V) \ -\ - /* List Sequence Input and Output */ \ - bool CMC_(PFX, _seq_push_front)(struct SNAME * _list_, V * values, size_t size); \ - bool CMC_(PFX, _seq_push_at)(struct SNAME * _list_, V * values, size_t size, size_t index); \ - bool CMC_(PFX, _seq_push_back)(struct SNAME * _list_, V * values, size_t size); \ - bool CMC_(PFX, _seq_pop_at)(struct SNAME * _list_, size_t from, size_t to); \ - struct SNAME *CMC_(PFX, _seq_sublist)(struct SNAME * _list_, size_t from, size_t to); - -#define CMC_EXT_CMC_LIST_SEQ_SOURCE_(PFX, SNAME, V) \ -\ - bool CMC_(PFX, _seq_push_front)(struct SNAME * _list_, V * values, size_t size) \ - { \ - if (size == 0) \ - { \ - _list_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ -\ - if (!CMC_(PFX, _fits)(_list_, size)) \ - { \ - if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) \ - return false; \ - } \ -\ - memmove(_list_->buffer + size, _list_->buffer, _list_->count * sizeof(V)); \ -\ - memcpy(_list_->buffer, values, size * sizeof(V)); \ -\ - _list_->count += size; \ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, create); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _seq_push_at)(struct SNAME * _list_, V * values, size_t size, size_t index) \ - { \ - if (size == 0) \ - { \ - _list_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ -\ - if (index > _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return false; \ - } \ -\ - if (index == 0) \ - return CMC_(PFX, _seq_push_front)(_list_, values, size); \ - else if (index == _list_->count) \ - return CMC_(PFX, _seq_push_back)(_list_, values, size); \ -\ - if (!CMC_(PFX, _fits)(_list_, size)) \ - { \ - if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) \ - return false; \ - } \ -\ - memmove(_list_->buffer + index + size, _list_->buffer + index, (_list_->count - index) * sizeof(V)); \ -\ - memcpy(_list_->buffer + index, values, size * sizeof(V)); \ -\ - _list_->count += size; \ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, create); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _seq_push_back)(struct SNAME * _list_, V * values, size_t size) \ - { \ - if (size == 0) \ - { \ - _list_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ -\ - if (!CMC_(PFX, _fits)(_list_, size)) \ - { \ - if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) \ - return false; \ - } \ -\ - memcpy(_list_->buffer + _list_->count, values, size * sizeof(V)); \ -\ - _list_->count += size; \ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, create); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _seq_pop_at)(struct SNAME * _list_, size_t from, size_t to) \ - { \ - if (from > to) \ - { \ - _list_->flag = CMC_FLAG_INVALID; \ - return false; \ - } \ -\ - if (to >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return false; \ - } \ -\ - size_t length = (to - from + 1); \ -\ - memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(V)); \ -\ - memset(_list_->buffer + _list_->count - length, 0, length * sizeof(V)); \ -\ - _list_->count -= to - from + 1; \ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, delete); \ -\ - return true; \ - } \ -\ - struct SNAME *CMC_(PFX, _seq_sublist)(struct SNAME * _list_, size_t from, size_t to) \ - { \ - if (from > to) \ - { \ - _list_->flag = CMC_FLAG_INVALID; \ - return NULL; \ - } \ -\ - if (to >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return NULL; \ - } \ -\ - size_t length = to - from + 1; \ -\ - struct SNAME *result = \ - CMC_(PFX, _new_custom)(length, _list_->f_val, _list_->alloc, CMC_CALLBACKS_GET(_list_)); \ -\ - if (!result) \ - { \ - _list_->flag = CMC_FLAG_ALLOC; \ - return NULL; \ - } \ -\ - memcpy(result->buffer, _list_->buffer, length * sizeof(V)); \ -\ - memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(V)); \ -\ - memset(_list_->buffer + _list_->count - length, 0, length * sizeof(V)); \ -\ - _list_->count -= length; \ - result->count = length; \ -\ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, delete); \ -\ - return result; \ - } - -/** - * STR - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_LIST_STR(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_EXT_CMC_LIST_STR_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_LIST_STR_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_LIST_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_LIST_STR_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_LIST_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_LIST_STR_PRIVATE_HEADER(PARAMS) \ - CMC_EXT_CMC_LIST_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_LIST_STR_PRIVATE_SOURCE(PARAMS) \ - CMC_EXT_CMC_LIST_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_LIST_STR_HEADER_(PFX, SNAME, V) \ -\ - bool CMC_(PFX, _to_string)(struct SNAME * _list_, FILE * fptr); \ - bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr, const char *start, const char *separator, \ - const char *end); - -#define CMC_EXT_CMC_LIST_STR_SOURCE_(PFX, SNAME, V) \ -\ - bool CMC_(PFX, _to_string)(struct SNAME * _list_, FILE * fptr) \ - { \ - struct SNAME *l_ = _list_; \ -\ - return 0 <= fprintf(fptr, \ - "struct %s<%s> " \ - "at %p { " \ - "buffer:%p, " \ - "capacity:%" PRIuMAX ", " \ - "count:%" PRIuMAX ", " \ - "flag:%d, " \ - "f_val:%p, " \ - "alloc:%p, " \ - "callbacks:%p }", \ - CMC_TO_STRING(SNAME), CMC_TO_STRING(V), l_, l_->buffer, l_->capacity, l_->count, l_->flag, \ - l_->f_val, l_->alloc, CMC_CALLBACKS_GET(l_)); \ - } \ -\ - bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr, const char *start, const char *separator, \ - const char *end) \ - { \ - fprintf(fptr, "%s", start); \ -\ - for (size_t i = 0; i < _list_->count; i++) \ - { \ - if (!_list_->f_val->str(fptr, _list_->buffer[i])) \ - return false; \ -\ - if (i + 1 < _list_->count) \ - fprintf(fptr, "%s", separator); \ - } \ -\ - fprintf(fptr, "%s", end); \ -\ - return true; \ - } - -#endif /* CMC_EXT_CMC_LIST_H */ diff --git a/src/ext_cmc_queue.h b/src/ext_cmc_queue.h deleted file mode 100644 index d411371..0000000 --- a/src/ext_cmc_queue.h +++ /dev/null @@ -1,388 +0,0 @@ -/** - * Copyright (c) 2019 Leonardo Vencovsky - * - * This file is part of the C Macro Collections Libray. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * ext_cmc_queue.h - * - * Creation Date: 05/06/2020 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -#ifndef CMC_EXT_CMC_QUEUE_H -#define CMC_EXT_CMC_QUEUE_H - -#include "cor_core.h" - -/** - * All the EXT parts of CMC Queue. - */ -#define CMC_EXT_CMC_QUEUE_PARTS ITER, STR - -/** - * ITER - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_QUEUE_ITER(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_EXT_CMC_QUEUE_ITER_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_QUEUE_ITER_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_QUEUE_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_QUEUE_ITER_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_QUEUE_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_QUEUE_ITER_PRIVATE_HEADER(PARAMS) \ - CMC_EXT_CMC_QUEUE_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_QUEUE_ITER_PRIVATE_SOURCE(PARAMS) \ - CMC_EXT_CMC_QUEUE_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_QUEUE_ITER_HEADER_(PFX, SNAME, V) \ -\ - /* Queue Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target queue */ \ - struct SNAME *target; \ -\ - /* Cursor's position (index) */ \ - size_t cursor; \ -\ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ -\ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ -\ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ -\ - /* Iterator Initialization */ \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ - /* Iterator Access */ \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); - -#define CMC_EXT_CMC_QUEUE_ITER_SOURCE_(PFX, SNAME, V) \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.cursor = target->front; \ - iter.index = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ -\ - return iter; \ - } \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ -\ - if (!CMC_(PFX, _empty)(target)) \ - { \ - if (iter.target->back == 0) \ - iter.cursor = iter.target->capacity - 1; \ - else \ - iter.cursor = iter.target->back - 1; \ -\ - iter.index = iter.target->count - 1; \ - } \ - else \ - { \ - iter.cursor = 0; \ - iter.index = 0; \ - } \ -\ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ -\ - return iter; \ - } \ -\ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ -\ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ -\ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->target->front; \ - iter->index = 0; \ - iter->start = true; \ - iter->end = false; \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - if (iter->target->back == 0) \ - iter->cursor = iter->target->capacity - 1; \ - else \ - iter->cursor = iter->target->back - 1; \ -\ - iter->index = iter->target->count - 1; \ -\ - iter->start = false; \ - iter->end = true; \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - iter->start = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor = (iter->cursor + 1) % (iter->target->capacity); \ - iter->index++; \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1; \ - iter->index--; \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->index + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->index + steps >= iter->target->count) \ - return false; \ -\ - iter->start = CMC_(PFX, _empty)(iter->target); \ -\ - iter->index += steps; \ - iter->cursor = (iter->cursor + steps) % iter->target->capacity; \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->index == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->index < steps) \ - return false; \ -\ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - iter->index -= steps; \ -\ - /* Prevent underflow */ \ - if (iter->cursor < steps) \ - iter->cursor += iter->target->capacity; \ -\ - iter->cursor -= steps; \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ -\ - if (iter->index > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ - else if (iter->index < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ -\ - return true; \ - } \ -\ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ -\ - return iter->target->buffer[iter->cursor]; \ - } \ -\ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return NULL; \ -\ - return &(iter->target->buffer[iter->cursor]); \ - } \ -\ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->index; \ - } - -/** - * STR - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_QUEUE_STR(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_EXT_CMC_QUEUE_STR_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_QUEUE_STR_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_QUEUE_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_QUEUE_STR_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_QUEUE_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_QUEUE_STR_PRIVATE_HEADER(PARAMS) \ - CMC_EXT_CMC_QUEUE_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_QUEUE_STR_PRIVATE_SOURCE(PARAMS) \ - CMC_EXT_CMC_QUEUE_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_QUEUE_STR_HEADER_(PFX, SNAME, V) \ -\ - bool CMC_(PFX, _to_string)(struct SNAME * _queue_, FILE * fptr); \ - bool CMC_(PFX, _print)(struct SNAME * _queue_, FILE * fptr, const char *start, const char *separator, \ - const char *end); - -#define CMC_EXT_CMC_QUEUE_STR_SOURCE_(PFX, SNAME, V) \ -\ - bool CMC_(PFX, _to_string)(struct SNAME * _queue_, FILE * fptr) \ - { \ - struct SNAME *q_ = _queue_; \ -\ - return 0 <= fprintf(fptr, \ - "struct %s<%s> " \ - "at %p { " \ - "buffer:%p, " \ - "capacity:%" PRIuMAX ", " \ - "count:%" PRIuMAX ", " \ - "front:%" PRIuMAX ", " \ - "back:%" PRIuMAX ", " \ - "flag:%d, " \ - "f_val:%p, " \ - "alloc:%p, " \ - "callbacks:%p }", \ - CMC_TO_STRING(SNAME), CMC_TO_STRING(V), q_, q_->buffer, q_->capacity, q_->count, \ - q_->front, q_->back, q_->flag, q_->f_val, q_->alloc, CMC_CALLBACKS_GET(q_)); \ - } \ -\ - bool CMC_(PFX, _print)(struct SNAME * _queue_, FILE * fptr, const char *start, const char *separator, \ - const char *end) \ - { \ - fprintf(fptr, "%s", start); \ -\ - for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \ - { \ - if (!_queue_->f_val->str(fptr, _queue_->buffer[i])) \ - return false; \ -\ - i = (i + 1) % _queue_->capacity; \ -\ - if (j + 1 < _queue_->count) \ - fprintf(fptr, "%s", separator); \ - } \ -\ - fprintf(fptr, "%s", end); \ -\ - return true; \ - } - -#endif /* CMC_EXT_CMC_QUEUE_H */ diff --git a/src/ext_cmc_sortedlist.h b/src/ext_cmc_sortedlist.h deleted file mode 100644 index 8d5189e..0000000 --- a/src/ext_cmc_sortedlist.h +++ /dev/null @@ -1,352 +0,0 @@ -/** - * Copyright (c) 2019 Leonardo Vencovsky - * - * This file is part of the C Macro Collections Libray. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * ext_cmc_sortedlist.h - * - * Creation Date: 06/06/2020 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -#ifndef CMC_EXT_CMC_SORTEDLIST_H -#define CMC_EXT_CMC_SORTEDLIST_H - -#include "cor_core.h" - -/** - * All the EXT parts of CMC SortedList. - */ -#define CMC_EXT_CMC_SORTEDLIST_PARTS ITER, STR - -/** - * ITER - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_SORTEDLIST_ITER(ACCESS, FILE, PARAMS) \ - CMC_(CMC_(CMC_EXT_CMC_SORTEDLIST_ITER_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_SORTEDLIST_ITER_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_SORTEDLIST_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_SORTEDLIST_ITER_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_SORTEDLIST_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_SORTEDLIST_ITER_PRIVATE_HEADER(PARAMS) \ - CMC_EXT_CMC_SORTEDLIST_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_SORTEDLIST_ITER_PRIVATE_SOURCE(PARAMS) \ - CMC_EXT_CMC_SORTEDLIST_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_SORTEDLIST_ITER_HEADER_(PFX, SNAME, V) \ -\ - /* List Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target list */ \ - struct SNAME *target; \ -\ - /* Cursor's position (index) */ \ - size_t cursor; \ -\ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ -\ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ -\ - /* Iterator Initialization */ \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ - /* Iterator Access */ \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); - -#define CMC_EXT_CMC_SORTEDLIST_ITER_SOURCE_(PFX, SNAME, V) \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - CMC_(PFX, _sort)(target); \ -\ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.cursor = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ -\ - return iter; \ - } \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - CMC_(PFX, _sort)(target); \ -\ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.cursor = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ -\ - if (!CMC_(PFX, _empty)(target)) \ - iter.cursor = target->count - 1; \ -\ - return iter; \ - } \ -\ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ -\ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ -\ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = 0; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->cursor = iter->target->count - 1; \ - iter->end = true; \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->cursor + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - iter->start = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor++; \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->cursor == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor--; \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->cursor + 1 == iter->target->count) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->cursor + steps >= iter->target->count) \ - return false; \ -\ - iter->start = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor += steps; \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->cursor == 0) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->cursor < steps) \ - return false; \ -\ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor -= steps; \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ -\ - if (iter->cursor > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->cursor - index); \ - else if (iter->cursor < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->cursor); \ -\ - return true; \ - } \ -\ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ -\ - return iter->target->buffer[iter->cursor]; \ - } \ -\ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->cursor; \ - } - -/** - * STR - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_SORTEDLIST_STR(ACCESS, FILE, PARAMS) \ - CMC_(CMC_(CMC_EXT_CMC_SORTEDLIST_STR_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_SORTEDLIST_STR_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_SORTEDLIST_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_SORTEDLIST_STR_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_SORTEDLIST_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_SORTEDLIST_STR_PRIVATE_HEADER(PARAMS) \ - CMC_EXT_CMC_SORTEDLIST_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_SORTEDLIST_STR_PRIVATE_SOURCE(PARAMS) \ - CMC_EXT_CMC_SORTEDLIST_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_SORTEDLIST_STR_HEADER_(PFX, SNAME, V) \ -\ - bool CMC_(PFX, _to_string)(struct SNAME * _list_, FILE * fptr); \ - bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr, const char *start, const char *separator, \ - const char *end); - -#define CMC_EXT_CMC_SORTEDLIST_STR_SOURCE_(PFX, SNAME, V) \ -\ - bool CMC_(PFX, _to_string)(struct SNAME * _list_, FILE * fptr) \ - { \ - struct SNAME *l_ = _list_; \ -\ - return 0 <= fprintf(fptr, \ - "struct %s<%s> " \ - "at %p { " \ - "buffer:%p, " \ - "capacity:%" PRIuMAX ", " \ - "count:%" PRIuMAX ", " \ - "is_sorted:%s, " \ - "flag:%d, " \ - "f_val:%p, " \ - "alloc:%p, " \ - "callbacks:%p }", \ - CMC_TO_STRING(SNAME), CMC_TO_STRING(V), l_, l_->buffer, l_->capacity, l_->count, \ - l_->is_sorted ? "true" : "false", l_->flag, l_->f_val, l_->alloc, CMC_CALLBACKS_GET(l_)); \ - } \ -\ - bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr, const char *start, const char *separator, \ - const char *end) \ - { \ - CMC_(PFX, _sort)(_list_); \ -\ - fprintf(fptr, "%s", start); \ -\ - for (size_t i = 0; i < _list_->count; i++) \ - { \ - if (!_list_->f_val->str(fptr, _list_->buffer[i])) \ - return false; \ -\ - if (i + 1 < _list_->count) \ - fprintf(fptr, "%s", separator); \ - } \ -\ - fprintf(fptr, "%s", end); \ -\ - return true; \ - } - -#endif /* CMC_EXT_CMC_SORTEDLIST_H */ diff --git a/src/ext_cmc_stack.h b/src/ext_cmc_stack.h deleted file mode 100644 index 145bf6e..0000000 --- a/src/ext_cmc_stack.h +++ /dev/null @@ -1,355 +0,0 @@ -/** - * Copyright (c) 2019 Leonardo Vencovsky - * - * This file is part of the C Macro Collections Libray. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * ext_cmc_stack.h - * - * Creation Date: 07/06/2020 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -#ifndef CMC_EXT_CMC_STACK_H -#define CMC_EXT_CMC_STACK_H - -#include "cor_core.h" - -/** - * All the EXT parts of CMC Stack. - */ -#define CMC_EXT_CMC_STACK_PARTS ITER, STR - -/** - * ITER - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_STACK_ITER(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_EXT_CMC_STACK_ITER_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_STACK_ITER_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_STACK_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_STACK_ITER_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_STACK_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_STACK_ITER_PRIVATE_HEADER(PARAMS) \ - CMC_EXT_CMC_STACK_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_STACK_ITER_PRIVATE_SOURCE(PARAMS) \ - CMC_EXT_CMC_STACK_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_STACK_ITER_HEADER_(PFX, SNAME, V) \ -\ - /* Stack Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target stack */ \ - struct SNAME *target; \ -\ - /* Cursor's position (index) */ \ - size_t cursor; \ -\ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ -\ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ -\ - /* Iterator Initialization */ \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ - /* Iterator Access */ \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); - -#define CMC_EXT_CMC_STACK_ITER_SOURCE_(PFX, SNAME, V) \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.cursor = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ -\ - if (!CMC_(PFX, _empty)(target)) \ - iter.cursor = target->count - 1; \ -\ - return iter; \ - } \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.cursor = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ -\ - return iter; \ - } \ -\ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ -\ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ -\ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = iter->target->count - 1; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->cursor = 0; \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->end = true; \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->cursor == 0) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - iter->start = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor--; \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->cursor + 1 == iter->target->count) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor++; \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->cursor == 0) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->cursor < steps) \ - return false; \ -\ - iter->start = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor -= steps; \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->cursor + 1 == iter->target->count) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->cursor + steps >= iter->target->count) \ - return false; \ -\ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - iter->cursor += steps; \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ -\ - if (iter->cursor > index) \ - return CMC_(PFX, _iter_advance)(iter, iter->cursor - index); \ - else if (iter->cursor < index) \ - return CMC_(PFX, _iter_rewind)(iter, index - iter->cursor); \ -\ - return true; \ - } \ -\ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ -\ - return iter->target->buffer[iter->cursor]; \ - } \ -\ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return NULL; \ -\ - return &(iter->target->buffer[iter->cursor]); \ - } \ -\ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return 0; \ -\ - return iter->target->count - 1 - iter->cursor; \ - } - -/** - * STR - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_STACK_STR(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_EXT_CMC_STACK_STR_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_STACK_STR_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_STACK_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_STACK_STR_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_STACK_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_STACK_STR_PRIVATE_HEADER(PARAMS) \ - CMC_EXT_CMC_STACK_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_STACK_STR_PRIVATE_SOURCE(PARAMS) \ - CMC_EXT_CMC_STACK_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_STACK_STR_HEADER_(PFX, SNAME, V) \ -\ - bool CMC_(PFX, _to_string)(struct SNAME * _stack_, FILE * fptr); \ - bool CMC_(PFX, _print)(struct SNAME * _stack_, FILE * fptr, const char *start, const char *separator, \ - const char *end); - -#define CMC_EXT_CMC_STACK_STR_SOURCE_(PFX, SNAME, V) \ -\ - bool CMC_(PFX, _to_string)(struct SNAME * _stack_, FILE * fptr) \ - { \ - struct SNAME *s_ = _stack_; \ -\ - return 0 <= fprintf(fptr, \ - "struct %s<%s> " \ - "at %p { " \ - "buffer:%p, " \ - "capacity:%" PRIuMAX ", " \ - "count:%" PRIuMAX ", " \ - "flag:%d, " \ - "f_val:%p, " \ - "alloc:%p, " \ - "callbacks:%p }", \ - CMC_TO_STRING(SNAME), CMC_TO_STRING(V), s_, s_->buffer, s_->capacity, s_->count, s_->flag, \ - s_->f_val, s_->alloc, CMC_CALLBACKS_GET(s_)); \ - } \ -\ - bool CMC_(PFX, _print)(struct SNAME * _stack_, FILE * fptr, const char *start, const char *separator, \ - const char *end) \ - { \ - fprintf(fptr, "%s", start); \ -\ - for (size_t i = _stack_->count; i > 0; i--) \ - { \ - if (!_stack_->f_val->str(fptr, _stack_->buffer[i - 1])) \ - return false; \ -\ - if (i - 1 != 0) \ - fprintf(fptr, "%s", separator); \ - } \ -\ - fprintf(fptr, "%s", end); \ -\ - return true; \ - } - -#endif /* CMC_EXT_CMC_STACK_H */ diff --git a/src/ext_cmc_treemap.h b/src/ext_cmc_treemap.h deleted file mode 100644 index 5b2952f..0000000 --- a/src/ext_cmc_treemap.h +++ /dev/null @@ -1,489 +0,0 @@ -/** - * Copyright (c) 2019 Leonardo Vencovsky - * - * This file is part of the C Macro Collections Libray. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * ext_cmc_treemap.h - * - * Creation Date: 08/06/2020 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -#ifndef CMC_EXT_CMC_TREEMAP_H -#define CMC_EXT_CMC_TREEMAP_H - -#include "cor_core.h" - -/** - * All the EXT parts of CMC TreeMap. - */ -#define CMC_EXT_CMC_TREEMAP_PARTS ITER, STR - -/** - * ITER - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_TREEMAP_ITER(ACCESS, FILE, PARAMS) \ - CMC_(CMC_(CMC_EXT_CMC_TREEMAP_ITER_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_TREEMAP_ITER_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_TREEMAP_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_TREEMAP_ITER_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_TREEMAP_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_TREEMAP_ITER_PRIVATE_HEADER(PARAMS) \ - CMC_EXT_CMC_TREEMAP_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_TREEMAP_ITER_PRIVATE_SOURCE(PARAMS) \ - CMC_EXT_CMC_TREEMAP_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_TREEMAP_ITER_HEADER_(PFX, SNAME, K, V) \ -\ - /* Treemap Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target treemap */ \ - struct SNAME *target; \ -\ - /* Cursor's current node */ \ - struct CMC_DEF_NODE(SNAME) * cursor; \ -\ - /* The first node in the iteration */ \ - struct CMC_DEF_NODE(SNAME) * first; \ -\ - /* The last node in the iteration */ \ - struct CMC_DEF_NODE(SNAME) * last; \ -\ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ -\ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ -\ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ -\ - /* Iterator Initialization */ \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ - /* Iterator Access */ \ - K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter); \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); - -#define CMC_EXT_CMC_TREEMAP_ITER_SOURCE_(PFX, SNAME, K, V) \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.cursor = target->root; \ - iter.first = NULL; \ - iter.last = NULL; \ - iter.index = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ -\ - if (!CMC_(PFX, _empty)(target)) \ - { \ - while (iter.cursor->left != NULL) \ - iter.cursor = iter.cursor->left; \ -\ - iter.first = iter.cursor; \ -\ - iter.last = target->root; \ - while (iter.last->right != NULL) \ - iter.last = iter.last->right; \ - } \ -\ - return iter; \ - } \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.cursor = target->root; \ - iter.first = NULL; \ - iter.last = NULL; \ - iter.index = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ -\ - if (!CMC_(PFX, _empty)(target)) \ - { \ - while (iter.cursor->right != NULL) \ - iter.cursor = iter.cursor->right; \ -\ - iter.last = iter.cursor; \ -\ - iter.first = target->root; \ - while (iter.first->left != NULL) \ - iter.first = iter.first->left; \ -\ - iter.index = target->count - 1; \ - } \ -\ - return iter; \ - } \ -\ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ -\ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ -\ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->index = 0; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - iter->cursor = iter->first; \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->index = iter->target->count - 1; \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->end = true; \ - iter->cursor = iter->last; \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->cursor == iter->last) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - iter->start = CMC_(PFX, _empty)(iter->target); \ -\ - if (iter->cursor->right != NULL) \ - { \ - iter->cursor = iter->cursor->right; \ -\ - while (iter->cursor->left != NULL) \ - iter->cursor = iter->cursor->left; \ -\ - iter->index++; \ -\ - return true; \ - } \ -\ - while (true) \ - { \ - if (iter->cursor->parent->left == iter->cursor) \ - { \ - iter->cursor = iter->cursor->parent; \ -\ - iter->index++; \ -\ - return true; \ - } \ -\ - iter->cursor = iter->cursor->parent; \ - } \ - } \ -\ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->cursor == iter->first) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - if (iter->cursor->left != NULL) \ - { \ - iter->cursor = iter->cursor->left; \ -\ - while (iter->cursor->right != NULL) \ - iter->cursor = iter->cursor->right; \ -\ - iter->index--; \ -\ - return true; \ - } \ -\ - while (true) \ - { \ - if (iter->cursor->parent->right == iter->cursor) \ - { \ - iter->cursor = iter->cursor->parent; \ -\ - iter->index--; \ -\ - return true; \ - } \ -\ - iter->cursor = iter->cursor->parent; \ - } \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->cursor == iter->last) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->index + steps >= iter->target->count) \ - return false; \ -\ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_next)(iter); \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->cursor == iter->first) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->index < steps) \ - return false; \ -\ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_prev)(iter); \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ -\ - if (iter->index > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ - else if (iter->index < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ -\ - return true; \ - } \ -\ - K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (K){ 0 }; \ -\ - return iter->cursor->key; \ - } \ -\ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ -\ - return iter->cursor->value; \ - } \ -\ - V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return NULL; \ -\ - return &(iter->cursor->value); \ - } \ -\ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->index; \ - } - -/** - * STR - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_TREEMAP_STR(ACCESS, FILE, PARAMS) \ - CMC_(CMC_(CMC_EXT_CMC_TREEMAP_STR_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_TREEMAP_STR_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_TREEMAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_TREEMAP_STR_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_TREEMAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_TREEMAP_STR_PRIVATE_HEADER(PARAMS) \ - CMC_EXT_CMC_TREEMAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_TREEMAP_STR_PRIVATE_SOURCE(PARAMS) \ - CMC_EXT_CMC_TREEMAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \ - CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_TREEMAP_STR_HEADER_(PFX, SNAME, K, V) \ -\ - bool CMC_(PFX, _to_string)(struct SNAME * _map_, FILE * fptr); \ - bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr, const char *start, const char *separator, \ - const char *end, const char *key_val_sep); - -#define CMC_EXT_CMC_TREEMAP_STR_SOURCE_(PFX, SNAME, K, V) \ -\ - bool CMC_(PFX, _to_string)(struct SNAME * _map_, FILE * fptr) \ - { \ - struct SNAME *m_ = _map_; \ -\ - return 0 <= fprintf(fptr, \ - "struct %s<%s, %s> " \ - "at %p { " \ - "root:%p, " \ - "count:%" PRIuMAX ", " \ - "flag:%d, " \ - "f_val:%p, " \ - "f_key:%p, " \ - "alloc:%p, " \ - "callbacks:%p }", \ - CMC_TO_STRING(SNAME), CMC_TO_STRING(K), CMC_TO_STRING(V), m_, m_->root, m_->count, \ - m_->flag, m_->f_key, m_->f_val, m_->alloc, CMC_CALLBACKS_GET(m_)); \ - } \ -\ - bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr, const char *start, const char *separator, \ - const char *end, const char *key_val_sep) \ - { \ - fprintf(fptr, "%s", start); \ -\ - struct CMC_DEF_NODE(SNAME) *root = _map_->root; \ -\ - bool left_done = false; \ -\ - size_t i = 0; \ - while (root) \ - { \ - if (!left_done) \ - { \ - while (root->left) \ - root = root->left; \ - } \ -\ - if (!_map_->f_key->str(fptr, root->key)) \ - return false; \ -\ - fprintf(fptr, "%s", key_val_sep); \ -\ - if (!_map_->f_val->str(fptr, root->value)) \ - return false; \ -\ - if (++i < _map_->count) \ - fprintf(fptr, "%s", separator); \ -\ - left_done = true; \ -\ - if (root->right) \ - { \ - left_done = false; \ - root = root->right; \ - } \ - else if (root->parent) \ - { \ - while (root->parent && root == root->parent->right) \ - root = root->parent; \ -\ - if (!root->parent) \ - break; \ -\ - root = root->parent; \ - } \ - else \ - break; \ - } \ -\ - fprintf(fptr, "%s", end); \ -\ - return true; \ - } - -#endif /* CMC_EXT_CMC_TREEMAP_H */ diff --git a/src/ext_cmc_treeset.h b/src/ext_cmc_treeset.h deleted file mode 100644 index a4cb620..0000000 --- a/src/ext_cmc_treeset.h +++ /dev/null @@ -1,699 +0,0 @@ -/** - * Copyright (c) 2019 Leonardo Vencovsky - * - * This file is part of the C Macro Collections Libray. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * ext_cmc_treeset.h - * - * Creation Date: 08/06/2020 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -#ifndef CMC_EXT_CMC_TREESET_H -#define CMC_EXT_CMC_TREESET_H - -#include "cor_core.h" - -/** - * All the EXT parts of CMC TreeSet. - */ -#define CMC_EXT_CMC_TREESET_PARTS ITER, SETF, STR - -/** - * ITER - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_TREESET_ITER(ACCESS, FILE, PARAMS) \ - CMC_(CMC_(CMC_EXT_CMC_TREESET_ITER_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_TREESET_ITER_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_TREESET_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_TREESET_ITER_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_TREESET_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_TREESET_ITER_PRIVATE_HEADER(PARAMS) \ - CMC_EXT_CMC_TREESET_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_TREESET_ITER_PRIVATE_SOURCE(PARAMS) \ - CMC_EXT_CMC_TREESET_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_TREESET_ITER_HEADER_(PFX, SNAME, V) \ -\ - /* Treeset Iterator */ \ - struct CMC_DEF_ITER(SNAME) \ - { \ - /* Target treeset */ \ - struct SNAME *target; \ -\ - /* Cursor's current node */ \ - struct CMC_DEF_NODE(SNAME) * cursor; \ -\ - /* The first node in the iteration */ \ - struct CMC_DEF_NODE(SNAME) * first; \ -\ - /* The last node in the iteration */ \ - struct CMC_DEF_NODE(SNAME) * last; \ -\ - /* Keeps track of relative index to the iteration of elements */ \ - size_t index; \ -\ - /* If the iterator has reached the start of the iteration */ \ - bool start; \ -\ - /* If the iterator has reached the end of the iteration */ \ - bool end; \ - }; \ -\ - /* Iterator Initialization */ \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target); \ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target); \ - /* Iterator State */ \ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - /* Iterator Movement */ \ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter); \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps); \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index); \ - /* Iterator Access */ \ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); - -#define CMC_EXT_CMC_TREESET_ITER_SOURCE_(PFX, SNAME, V) \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.cursor = target->root; \ - iter.first = NULL; \ - iter.last = NULL; \ - iter.index = 0; \ - iter.start = true; \ - iter.end = CMC_(PFX, _empty)(target); \ -\ - if (!CMC_(PFX, _empty)(target)) \ - { \ - while (iter.cursor->left != NULL) \ - iter.cursor = iter.cursor->left; \ -\ - iter.first = iter.cursor; \ -\ - iter.last = target->root; \ - while (iter.last->right != NULL) \ - iter.last = iter.last->right; \ - } \ -\ - return iter; \ - } \ -\ - struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \ - { \ - struct CMC_DEF_ITER(SNAME) iter; \ -\ - iter.target = target; \ - iter.cursor = target->root; \ - iter.first = NULL; \ - iter.last = NULL; \ - iter.index = 0; \ - iter.start = CMC_(PFX, _empty)(target); \ - iter.end = true; \ -\ - if (!CMC_(PFX, _empty)(target)) \ - { \ - while (iter.cursor->right != NULL) \ - iter.cursor = iter.cursor->right; \ -\ - iter.last = iter.cursor; \ -\ - iter.first = target->root; \ - while (iter.first->left != NULL) \ - iter.first = iter.first->left; \ -\ - iter.index = target->count - 1; \ - } \ -\ - return iter; \ - } \ -\ - bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->start; \ - } \ -\ - bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return CMC_(PFX, _empty)(iter->target) || iter->end; \ - } \ -\ - bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->index = 0; \ - iter->start = true; \ - iter->end = CMC_(PFX, _empty)(iter->target); \ - iter->cursor = iter->first; \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (!CMC_(PFX, _empty)(iter->target)) \ - { \ - iter->index = iter->target->count - 1; \ - iter->start = CMC_(PFX, _empty)(iter->target); \ - iter->end = true; \ - iter->cursor = iter->last; \ -\ - return true; \ - } \ -\ - return false; \ - } \ -\ - bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->cursor == iter->last) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - iter->start = CMC_(PFX, _empty)(iter->target); \ -\ - if (iter->cursor->right != NULL) \ - { \ - iter->cursor = iter->cursor->right; \ -\ - while (iter->cursor->left != NULL) \ - iter->cursor = iter->cursor->left; \ -\ - iter->index++; \ -\ - return true; \ - } \ -\ - while (true) \ - { \ - if (iter->cursor->parent->left == iter->cursor) \ - { \ - iter->cursor = iter->cursor->parent; \ -\ - iter->index++; \ -\ - return true; \ - } \ -\ - iter->cursor = iter->cursor->parent; \ - } \ - } \ -\ - bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->cursor == iter->first) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - iter->end = CMC_(PFX, _empty)(iter->target); \ -\ - if (iter->cursor->left != NULL) \ - { \ - iter->cursor = iter->cursor->left; \ -\ - while (iter->cursor->right != NULL) \ - iter->cursor = iter->cursor->right; \ -\ - iter->index--; \ -\ - return true; \ - } \ -\ - while (true) \ - { \ - if (iter->cursor->parent->right == iter->cursor) \ - { \ - iter->cursor = iter->cursor->parent; \ -\ - iter->index--; \ -\ - return true; \ - } \ -\ - iter->cursor = iter->cursor->parent; \ - } \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->end) \ - return false; \ -\ - if (iter->cursor == iter->last) \ - { \ - iter->end = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->index + steps >= iter->target->count) \ - return false; \ -\ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_next)(iter); \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator moved */ \ - bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps) \ - { \ - if (iter->start) \ - return false; \ -\ - if (iter->cursor == iter->first) \ - { \ - iter->start = true; \ - return false; \ - } \ -\ - if (steps == 0 || iter->index < steps) \ - return false; \ -\ - for (size_t i = 0; i < steps; i++) \ - CMC_(PFX, _iter_prev)(iter); \ -\ - return true; \ - } \ -\ - /* Returns true only if the iterator was able to be positioned at the */ \ - /* given index */ \ - bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index) \ - { \ - if (index >= iter->target->count) \ - return false; \ -\ - if (iter->index > index) \ - return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \ - else if (iter->index < index) \ - return CMC_(PFX, _iter_advance)(iter, index - iter->index); \ -\ - return true; \ - } \ -\ - V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - if (CMC_(PFX, _empty)(iter->target)) \ - return (V){ 0 }; \ -\ - return iter->cursor->value; \ - } \ -\ - size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \ - { \ - return iter->index; \ - } - -/** - * SETF - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_TREESET_SETF(ACCESS, FILE, PARAMS) \ - CMC_(CMC_(CMC_EXT_CMC_TREESET_SETF_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_TREESET_SETF_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_TREESET_SETF_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_TREESET_SETF_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_TREESET_SETF_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_TREESET_SETF_PRIVATE_HEADER(PARAMS) \ - CMC_EXT_CMC_TREESET_SETF_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_TREESET_SETF_PRIVATE_SOURCE(PARAMS) \ - CMC_EXT_CMC_TREESET_SETF_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_TREESET_SETF_HEADER_(PFX, SNAME, V) \ -\ - /* Set Operations */ \ - struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, struct SNAME * _set2_); \ - struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, struct SNAME * _set2_); \ - bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_); \ - bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, struct SNAME * _set2_); \ - bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, struct SNAME * _set2_); \ - bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, struct SNAME * _set2_); \ - bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, struct SNAME * _set2_); - -#define CMC_EXT_CMC_TREESET_SETF_SOURCE_(PFX, SNAME, V) \ -\ - struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - struct SNAME *_set_r_ = CMC_(PFX, _new_custom)(_set1_->f_val, _set1_->alloc, NULL); \ -\ - if (!_set_r_) \ - return NULL; \ -\ - struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ - struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter1); CMC_(PFX, _iter_next)(&iter1)) \ - { \ - CMC_(PFX, _insert)(_set_r_, CMC_(PFX, _iter_value)(&iter1)); \ - } \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter2); CMC_(PFX, _iter_next)(&iter2)) \ - { \ - CMC_(PFX, _insert)(_set_r_, CMC_(PFX, _iter_value)(&iter2)); \ - } \ -\ - CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ -\ - return _set_r_; \ - } \ -\ - struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - struct SNAME *_set_r_ = CMC_(PFX, _new_custom)(_set1_->f_val, _set1_->alloc, NULL); \ -\ - if (!_set_r_) \ - return NULL; \ -\ - /** TODO Should this compare count or capacity? */ \ - struct SNAME *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; \ - struct SNAME *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; \ -\ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_A_); \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ -\ - if (CMC_(PFX, _impl_get_node)(_set_B_, value) != NULL) \ - CMC_(PFX, _insert)(_set_r_, value); \ - } \ -\ - CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ -\ - return _set_r_; \ - } \ -\ - struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - struct SNAME *_set_r_ = CMC_(PFX, _new_custom)(_set1_->f_val, _set1_->alloc, NULL); \ -\ - if (!_set_r_) \ - return NULL; \ -\ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ -\ - if (CMC_(PFX, _impl_get_node)(_set2_, value) == NULL) \ - CMC_(PFX, _insert)(_set_r_, value); \ - } \ -\ - CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ -\ - return _set_r_; \ - } \ -\ - struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - struct SNAME *_set_r_ = CMC_(PFX, _new_custom)(_set1_->f_val, _set1_->alloc, NULL); \ -\ - if (!_set_r_) \ - return NULL; \ -\ - struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \ - struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter1); CMC_(PFX, _iter_next)(&iter1)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter1); \ -\ - if (CMC_(PFX, _impl_get_node)(_set2_, value) == NULL) \ - CMC_(PFX, _insert)(_set_r_, value); \ - } \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter2); CMC_(PFX, _iter_next)(&iter2)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter2); \ -\ - if (CMC_(PFX, _impl_get_node)(_set1_, value) == NULL) \ - CMC_(PFX, _insert)(_set_r_, value); \ - } \ -\ - CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \ -\ - return _set_r_; \ - } \ -\ - /* Is _set1_ a subset of _set2_ ? */ \ - /* A set X is a subset of a set Y when: X <= Y */ \ - /* If X is a subset of Y, then Y is a superset of X */ \ - bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - /* If the cardinality of _set1_ is greater than that of _set2_ */ \ - /* then it is safe to say that _set1_ can't be a subset of _set2_ */ \ - if (_set1_->count > _set2_->count) \ - return false; \ -\ - /* The empty set is a subset of all sets */ \ - if (CMC_(PFX, _empty)(_set1_)) \ - return true; \ -\ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ -\ - if (CMC_(PFX, _impl_get_node)(_set2_, value) == NULL) \ - return false; \ - } \ -\ - return true; \ - } \ -\ - /* Is _set1_ a superset of _set2_ ? */ \ - /* A set X is a superset of a set Y when: X >= Y */ \ - /* If X is a superset of Y, then Y is a subset of X */ \ - bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - return CMC_(PFX, _is_subset)(_set2_, _set1_); \ - } \ -\ - /* Is _set1_ a proper subset of _set2_ ? */ \ - /* A set X is a proper subset of a set Y when: X < Y */ \ - /* If X is a proper subset of Y, then Y is a proper superset of X */ \ - bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - /* If the cardinality of _set1_ is greater than or equal to that */ \ - /* of _set2_, then it is safe to say that _set1_ can't be a proper */ \ - /* subset of _set2_ */ \ - if (_set1_->count >= _set2_->count) \ - return false; \ -\ - if (CMC_(PFX, _empty)(_set1_)) \ - { \ - /* The empty set is a proper subset of all non-empty sets */ \ - if (!CMC_(PFX, _empty)(_set2_)) \ - return true; \ - /* The empty set is not a proper subset of itself (this is true */ \ - /* for any set) */ \ - else \ - return false; \ - } \ -\ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ -\ - if (CMC_(PFX, _impl_get_node)(_set2_, value) == NULL) \ - return false; \ - } \ -\ - return true; \ - } \ -\ - /* Is _set1_ a proper superset of _set2_ ? */ \ - /* A set X is a proper superset of a set Y when: X > Y */ \ - /* If X is a proper superset of Y, then Y is a proper subset of X */ \ - bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - return CMC_(PFX, _is_proper_subset)(_set2_, _set1_); \ - } \ -\ - /* Is _set1_ a disjointset of _set2_ ? */ \ - /* A set X is a disjointset of a set Y if their intersection is empty, */ \ - /* that is, if there are no elements in common between the two */ \ - bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, struct SNAME * _set2_) \ - { \ - /* The intersection of an empty set with any other set will result */ \ - /* in an empty set */ \ - if (CMC_(PFX, _empty)(_set1_)) \ - return true; \ -\ - struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \ -\ - for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \ - { \ - V value = CMC_(PFX, _iter_value)(&iter); \ -\ - if (CMC_(PFX, _impl_get_node)(_set2_, value) != NULL) \ - return false; \ - } \ -\ - return true; \ - } - -/** - * STR - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_EXT_CMC_TREESET_STR(ACCESS, FILE, PARAMS) \ - CMC_(CMC_(CMC_EXT_CMC_TREESET_STR_, ACCESS), CMC_(_, FILE))(PARAMS) - -#define CMC_EXT_CMC_TREESET_STR_PUBLIC_HEADER(PARAMS) \ - CMC_EXT_CMC_TREESET_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_TREESET_STR_PUBLIC_SOURCE(PARAMS) \ - CMC_EXT_CMC_TREESET_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_TREESET_STR_PRIVATE_HEADER(PARAMS) \ - CMC_EXT_CMC_TREESET_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_TREESET_STR_PRIVATE_SOURCE(PARAMS) \ - CMC_EXT_CMC_TREESET_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_EXT_CMC_TREESET_STR_HEADER_(PFX, SNAME, V) \ -\ - bool CMC_(PFX, _to_string)(struct SNAME * _set_, FILE * fptr); \ - bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr, const char *start, const char *separator, \ - const char *end); - -#define CMC_EXT_CMC_TREESET_STR_SOURCE_(PFX, SNAME, V) \ -\ - bool CMC_(PFX, _to_string)(struct SNAME * _set_, FILE * fptr) \ - { \ - struct SNAME *s_ = _set_; \ -\ - return 0 <= fprintf(fptr, \ - "struct %s<%s> " \ - "at %p { " \ - "root:%p, " \ - "count:%" PRIuMAX ", " \ - "flag:%d, " \ - "f_val:%p, " \ - "alloc:%p, " \ - "callbacks:%p }", \ - CMC_TO_STRING(SNAME), CMC_TO_STRING(V), s_, s_->root, s_->count, s_->flag, s_->f_val, \ - s_->alloc, CMC_CALLBACKS_GET(s_)); \ - } \ -\ - bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr, const char *start, const char *separator, \ - const char *end) \ - { \ - fprintf(fptr, "%s", start); \ -\ - struct CMC_DEF_NODE(SNAME) *root = _set_->root; \ -\ - bool left_done = false; \ -\ - size_t i = 0; \ - while (root) \ - { \ - if (!left_done) \ - { \ - while (root->left) \ - root = root->left; \ - } \ -\ - if (!_set_->f_val->str(fptr, root->value)) \ - return false; \ -\ - if (++i < _set_->count) \ - fprintf(fptr, "%s", separator); \ -\ - left_done = true; \ -\ - if (root->right) \ - { \ - left_done = false; \ - root = root->right; \ - } \ - else if (root->parent) \ - { \ - while (root->parent && root == root->parent->right) \ - root = root->parent; \ -\ - if (!root->parent) \ - break; \ -\ - root = root->parent; \ - } \ - else \ - break; \ - } \ -\ - fprintf(fptr, "%s", end); \ -\ - return true; \ - } - -#endif /* CMC_EXT_CMC_TREESET_H */ diff --git a/src/macro_collections.h b/src/macro_collections.h deleted file mode 100644 index 022b480..0000000 --- a/src/macro_collections.h +++ /dev/null @@ -1,293 +0,0 @@ -/** - * Copyright (c) 2019 Leonardo Vencovsky - * - * This file is part of the C Macro Collections Libray. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * macro_collections.h - * - * Creation Date: 11/02/2019 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -/** - * This file provides everything from the C Macro Collections library. - * - * Every data structure and features are available through this header. There is - * also three macros that can help you generate whichever Collection you need - * from any given sub-library. They are: - * - * - C_MACRO_COLLECTIONS - * - C_MACRO_COLLECTIONS_INLINE - * - C_MACRO_COLLECTIONS_EXTENDED - * - C_MACRO_COLLECTIONS_EXTENDED_HEADER - * - C_MACRO_COLLECTIONS_EXTENDED_SOURCE - * - C_MACRO_COLLECTIONS_ALL - * - C_MACRO_COLLECTIONS_ALL_HEADER - * - C_MACRO_COLLECTIONS_ALL_SOURCE - */ -#ifndef CMC_MACRO_COLLECTIONS_H -#define CMC_MACRO_COLLECTIONS_H - -// clang-format off -#include "cmc_bitset.h" /* Added in 30/04/2020 */ -#include "cmc_deque.h" /* Added in 20/03/2019 */ -#include "cmc_hashbidimap.h" /* Added in 26/09/2019 */ -#include "cmc_hashmap.h" /* Added in 03/04/2019 */ -#include "cmc_hashmultimap.h" /* Added in 26/04/2019 */ -#include "cmc_hashmultiset.h" /* Added in 10/04/2019 */ -#include "cmc_hashset.h" /* Added in 01/04/2019 */ -#include "cmc_heap.h" /* Added in 25/03/2019 */ -#include "cmc_intervalheap.h" /* Added in 06/07/2019 */ -#include "cmc_linkedlist.h" /* Added in 22/03/2019 */ -#include "cmc_list.h" /* Added in 12/02/2019 */ -#include "cmc_queue.h" /* Added in 15/02/2019 */ -#include "cmc_sortedlist.h" /* Added in 17/09/2019 */ -#include "cmc_stack.h" /* Added in 14/02/2019 */ -#include "cmc_treemap.h" /* Added in 28/03/2019 */ -#include "cmc_treeset.h" /* Added in 27/03/2019 */ - -#include "cor_alloc.h" /* Added in 24/05/2020 */ -#include "cor_bitset.h" /* Added in 20/05/2020 */ -#include "cor_callbacks.h" /* Added in 24/05/2020 */ -#include "cor_core.h" /* Added in 17/03/2020 */ -#include "cor_flags.h" /* Added in 14/05/2020 */ -#include "cor_ftable.h" /* Added in 27/05/2020 */ -#include "cor_hashtable.h" /* Added in 17/03/2020 */ -#include "cor_heap.h" /* Added in 01/06/2020 */ - -#include "ext_cmc_bitset.h" /* Added in 08/06/2020 */ -#include "ext_cmc_deque.h" /* Added in 25/05/2020 */ -#include "ext_cmc_hashbidimap.h" /* Added in 26/05/2020 */ -#include "ext_cmc_hashmap.h" /* Added in 25/05/2020 */ -#include "ext_cmc_hashmultimap.h" /* Added in 29/05/2020 */ -#include "ext_cmc_hashmultiset.h" /* Added in 30/05/2020 */ -#include "ext_cmc_hashset.h" /* Added in 31/05/2020 */ -#include "ext_cmc_heap.h" /* Added in 01/06/2020 */ -#include "ext_cmc_intervalheap.h" /* Added in 02/06/2020 */ -#include "ext_cmc_linkedlist.h" /* Added in 03/06/2020 */ -#include "ext_cmc_list.h" /* Added in 04/06/2020 */ -#include "ext_cmc_queue.h" /* Added in 05/06/2020 */ -#include "ext_cmc_sortedlist.h" /* Added in 06/06/2020 */ -#include "ext_cmc_stack.h" /* Added in 07/06/2020 */ -#include "ext_cmc_treemap.h" /* Added in 08/06/2020 */ -#include "ext_cmc_treeset.h" /* Added in 08/06/2020 */ -#include "ext_sac_list.h" /* Added in 08/06/2020 */ - -#include "sac_list.h" /* Added in 06/10/2020 */ - -#include "utl_assert.h" /* Added in 27/06/2019 */ -#include "utl_foreach.h" /* Added in 25/02/2019 */ -#include "utl_futils.h" /* Added in 15/04/2020 */ -#include "utl_log.h" /* Added in 21/06/2019 */ -#include "utl_mutex.h" /* Added in 14/05/2020 */ -#include "utl_test.h" /* Added in 26/06/2019 */ -#include "utl_thread.h" /* Added in 14/05/2020 */ -#include "utl_timer.h" /* Added in 12/04/2019 */ -// clang-format on - -/** - * C_MACRO_COLLECTIONS - * - * Generate a specific part of a specific collection from a specific library. - * - * \param LIB The collection's sub-library - * \param COLLECTION The name of the collection in all uppercase - * \param PART The part of the collection (either CORE or one available at EXT) - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, ACCESS, FILE, PARAMS) \ - C_MACRO_COLLECTIONS_(LIB, COLLECTION, PART, ACCESS, FILE)(PARAMS) - -#define C_MACRO_COLLECTIONS_(LIB, COLLECTION, PART, ACCESS, FILE) CMC_##LIB##_##COLLECTION##_##PART##_##ACCESS##_##FILE - -/** - * C_MACRO_COLLECTIONS_INLINE - * - * Generates both HEADER and SOURCE one after the other of a certain PART of a certain LIB. - * - * \param LIB The collection's sub-library - * \param COLLECTION The name of the collection in all uppercase - * \param PART The part of the collection (either CORE or one available at EXT) - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define C_MACRO_COLLECTIONS_INLINE(LIB, COLLECTION, PART, PARAMS) \ - C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, PUBLIC, HEADER, PARAMS) \ - C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, PUBLIC, SOURCE, PARAMS) - -/** - * C_MACRO_COLLECTIONS_EXTENDED - * - * Generate the CORE of a collection along with one or more part from EXT. The - * headers are generated first, then the source code. - * - * \param LIB The collection's sub-library - * \param COLLECTION The name of the collection in all uppercase - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - * \param PARTS A non-empty tuple of all desired EXT parts - */ -#define C_MACRO_COLLECTIONS_EXTENDED(LIB, COLLECTION, PARAMS, PARTS) \ - C_MACRO_COLLECTIONS_EXTENDED_HEADER(LIB, COLLECTION, PUBLIC, PARAMS, PARTS) \ - C_MACRO_COLLECTIONS_EXTENDED_SOURCE(LIB, COLLECTION, PUBLIC, PARAMS, PARTS) - -/** - * C_MACRO_COLLECTIONS_EXTENDED_HEADER - * - * Generate all headers of CORE and the specified header parts of a collection. - * - * \param LIB The collection's sub-library - * \param COLLECTION The name of the collection in all uppercase - * \param ACCESS Either PUBLIC or PRIVATE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - * \param PARTS A non-empty tuple of all desired EXT parts - */ -#define C_MACRO_COLLECTIONS_EXTENDED_HEADER(LIB, COLLECTION, ACCESS, PARAMS, PARTS) \ - C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, ACCESS, HEADER, PARAMS) \ - CMC_MAP(CMC_(EXT_, LIB), COLLECTION, ACCESS, HEADER, PARAMS, CMC_EVAL PARTS) - -/** - * C_MACRO_COLLECTIONS_EXTENDED_SOURCE - * - * Generate all sources of CORE and the specified source parts of a collection. - * - * \param LIB The collection's sub-library - * \param COLLECTION The name of the collection in all uppercase - * \param ACCESS Either PUBLIC or PRIVATE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - * \param PARTS A non-empty tuple of all desired EXT parts - */ -#define C_MACRO_COLLECTIONS_EXTENDED_SOURCE(LIB, COLLECTION, ACCESS, PARAMS, PARTS) \ - C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, ACCESS, SOURCE, PARAMS) \ - CMC_MAP(CMC_(EXT_, LIB), COLLECTION, ACCESS, SOURCE, PARAMS, CMC_EVAL PARTS) - -/** - * C_MACRO_COLLECTIONS_ALL - * - * Generate everything provided by a collection included in the EXT library. The - * headers are generated first, then the source code. - * - * \param LIB The collection's library - * \param COLLECTION The name of the collection in all uppercase - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define C_MACRO_COLLECTIONS_ALL(LIB, COLLECTION, PARAMS) \ - C_MACRO_COLLECTIONS_ALL_HEADER(LIB, COLLECTION, PUBLIC, PARAMS) \ - C_MACRO_COLLECTIONS_ALL_SOURCE(LIB, COLLECTION, PUBLIC, PARAMS) - -/** - * C_MACRO_COLLECTIONS_ALL_HEADER - * - * Generates all headers (CORE and those at EXT) from a given collection. - * - * \param LIB The collection's library - * \param COLLECTION The name of the collection in all uppercase - * \param ACCESS Either PUBLIC or PRIVATE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define C_MACRO_COLLECTIONS_ALL_HEADER(LIB, COLLECTION, ACCESS, PARAMS) \ - C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, ACCESS, HEADER, PARAMS) \ - CMC_MAP(CMC_(EXT_, LIB), COLLECTION, ACCESS, HEADER, PARAMS, C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION)) - -/** - * C_MACRO_COLLECTIONS_ALL_SOURCE - * - * Generates all sources (CORE and those at EXT) from a given collection. - * - * \param LIB The collection's library - * \param COLLECTION The name of the collection in all uppercase - * \param ACCESS Either PUBLIC or PRIVATE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V - */ -#define C_MACRO_COLLECTIONS_ALL_SOURCE(LIB, COLLECTION, ACCESS, PARAMS) \ - C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE, ACCESS, SOURCE, PARAMS) \ - CMC_MAP(CMC_(EXT_, LIB), COLLECTION, ACCESS, SOURCE, PARAMS, C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION)) - -/** - * C_MACRO_COLLECTIONS_PARTS - * - * Gets the macro with all EXT parts of a collection. Every collection has this - * macro defined in the EXT libraries. - */ -#define C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION) CMC_EXT_##LIB##_##COLLECTION##_PARTS, - -/* Evaluates a tuple so that (A, B) -> A, B, */ -#define CMC_EVAL(...) __VA_ARGS__, - -/** - * A __VA_ARGS__ argument counter. This argument counter is slightly shifted: - * - * CMC_NARG(HELLO) -> 0 - * CMC_NARG(HELLO,) -> 1 - * CMC_NARG(HELLO, WORLD,) -> 2 - */ -#define CMC_NARG(...) CMC_NARG_(__VA_ARGS__, CMC_SEQ_N()) -#define CMC_NARG_(...) CMC_ARG_N(__VA_ARGS__) -#define CMC_ARG_N(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, \ - _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, \ - _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, \ - _62, _63, N, ...) \ - N -#define CMC_SEQ_N() \ - 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, \ - 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, \ - 7, 6, 5, 4, 3, 2, 1, 0 - -/* Generates the FILE for each part (__VA_ARGS__) of a collection */ -#define CMC_MAP(LIB, COLLECTION, ACCESS, FILE, PARAMS, ...) \ - CMC_(CMC_MAP_, CMC_NARG(__VA_ARGS__)) \ - (LIB, COLLECTION, ACCESS, FILE, PARAMS, __VA_ARGS__) - -#define CMC_MAP_9(LIB, COLLECTION, ACCESS, FILE, PARAMS, PART, ...) \ - C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, ACCESS, FILE, PARAMS) \ - CMC_MAP_8(LIB, COLLECTION, ACCESS, FILE, PARAMS, __VA_ARGS__) -#define CMC_MAP_8(LIB, COLLECTION, ACCESS, FILE, PARAMS, PART, ...) \ - C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, ACCESS, FILE, PARAMS) \ - CMC_MAP_7(LIB, COLLECTION, ACCESS, FILE, PARAMS, __VA_ARGS__) -#define CMC_MAP_7(LIB, COLLECTION, ACCESS, FILE, PARAMS, PART, ...) \ - C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, ACCESS, FILE, PARAMS) \ - CMC_MAP_6(LIB, COLLECTION, ACCESS, FILE, PARAMS, __VA_ARGS__) -#define CMC_MAP_6(LIB, COLLECTION, ACCESS, FILE, PARAMS, PART, ...) \ - C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, ACCESS, FILE, PARAMS) \ - CMC_MAP_5(LIB, COLLECTION, ACCESS, FILE, PARAMS, __VA_ARGS__) -#define CMC_MAP_5(LIB, COLLECTION, ACCESS, FILE, PARAMS, PART, ...) \ - C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, ACCESS, FILE, PARAMS) \ - CMC_MAP_4(LIB, COLLECTION, ACCESS, FILE, PARAMS, __VA_ARGS__) -#define CMC_MAP_4(LIB, COLLECTION, ACCESS, FILE, PARAMS, PART, ...) \ - C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, ACCESS, FILE, PARAMS) \ - CMC_MAP_3(LIB, COLLECTION, ACCESS, FILE, PARAMS, __VA_ARGS__) -#define CMC_MAP_3(LIB, COLLECTION, ACCESS, FILE, PARAMS, PART, ...) \ - C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, ACCESS, FILE, PARAMS) \ - CMC_MAP_2(LIB, COLLECTION, ACCESS, FILE, PARAMS, __VA_ARGS__) -#define CMC_MAP_2(LIB, COLLECTION, ACCESS, FILE, PARAMS, PART, ...) \ - C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, ACCESS, FILE, PARAMS) \ - CMC_MAP_1(LIB, COLLECTION, ACCESS, FILE, PARAMS, __VA_ARGS__) -#define CMC_MAP_1(LIB, COLLECTION, ACCESS, FILE, PARAMS, PART, ...) \ - C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, ACCESS, FILE, PARAMS) \ - CMC_MAP_0(LIB, COLLECTION, ACCESS, FILE, PARAMS, __VA_ARGS__) -#define CMC_MAP_0(LIB, COLLECTION, ACCESS, FILE, PARAMS, ...) - -#endif /* CMC_MACRO_COLLECTIONS_H */ diff --git a/src/sac_list.h b/src/sac_list.h deleted file mode 100644 index 05dff79..0000000 --- a/src/sac_list.h +++ /dev/null @@ -1,534 +0,0 @@ -/** - * Copyright (c) 2019 Leonardo Vencovsky - * - * This file is part of the C Macro Collections Libray. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * sac_list.h - * - * Creation Date: 06/10/2020 - * - * Authors: - * Leonardo Vencovsky (https://github.com/LeoVen) - * - */ - -/** - * List - * - * A List that is stored in a fixed sized array. It works very much like a list - * but is not resizeable and doesn't make use of dynamic memory internally. - */ - -/* TODO : Remove all allocations */ - -#ifndef CMC_SAC_LIST_H -#define CMC_SAC_LIST_H - -/* ------------------------------------------------------------------------- - * Core functionalities of the C Macro Collections Library - * ------------------------------------------------------------------------- */ -#include "cor_core.h" - -/** - * Core List implementation - * - * \param ACCESS Either PUBLIC or PRIVATE - * \param FILE Either HEADER or SOURCE - * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V) - */ -#define CMC_SAC_LIST_CORE(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_SAC_LIST_CORE_, ACCESS), CMC_(_, FILE))(PARAMS) - -/* PRIVATE or PUBLIC solver */ -#define CMC_SAC_LIST_CORE_PUBLIC_HEADER(PARAMS) \ - CMC_SAC_LIST_CORE_STRUCT(PARAMS) \ - CMC_SAC_LIST_CORE_HEADER(PARAMS) - -#define CMC_SAC_LIST_CORE_PUBLIC_SOURCE(PARAMS) CMC_SAC_LIST_CORE_SOURCE(PARAMS) - -#define CMC_SAC_LIST_CORE_PRIVATE_HEADER(PARAMS) \ - struct CMC_PARAM_SNAME(PARAMS); \ - CMC_SAC_LIST_CORE_HEADER(PARAMS) - -#define CMC_SAC_LIST_CORE_PRIVATE_SOURCE(PARAMS) \ - CMC_SAC_LIST_CORE_STRUCT(PARAMS) \ - CMC_SAC_LIST_CORE_SOURCE(PARAMS) - -/* Lowest level API */ -#define CMC_SAC_LIST_CORE_STRUCT(PARAMS) \ - CMC_SAC_LIST_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SIZE(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_SAC_LIST_CORE_HEADER(PARAMS) \ - CMC_SAC_LIST_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SIZE(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -#define CMC_SAC_LIST_CORE_SOURCE(PARAMS) \ - CMC_SAC_LIST_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SIZE(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS)) - -/* ------------------------------------------------------------------------- - * Struct - * ------------------------------------------------------------------------- */ -#define CMC_SAC_LIST_CORE_STRUCT_(PFX, SIZE, SNAME, V) \ -\ - /* List Structure */ \ - struct SNAME \ - { \ - /* Dynamic array of elements */ \ - V buffer[SIZE]; \ -\ - /* Current amount of elements */ \ - size_t count; \ -\ - /* Flags indicating errors or success */ \ - int flag; \ -\ - /* Value function table */ \ - struct CMC_DEF_FVAL(SNAME) * f_val; \ -\ - /* Custom callback functions */ \ - CMC_CALLBACKS_DECL; \ - }; - -/* ------------------------------------------------------------------------- - * Header - * ------------------------------------------------------------------------- */ -#define CMC_SAC_LIST_CORE_HEADER_(PFX, SIZE, SNAME, V) \ -\ - /* Value struct function table */ \ - struct CMC_DEF_FVAL(SNAME) \ - { \ - /* Comparator function */ \ - CMC_DEF_FTAB_CMP(V); \ -\ - /* Copy function */ \ - CMC_DEF_FTAB_CPY(V); \ -\ - /* To string function */ \ - CMC_DEF_FTAB_STR(V); \ -\ - /* Free from memory function */ \ - CMC_DEF_FTAB_FREE(V); \ -\ - /* Hash function */ \ - CMC_DEF_FTAB_HASH(V); \ -\ - /* Priority function */ \ - CMC_DEF_FTAB_PRI(V); \ - }; \ -\ - /* Collection Functions */ \ - /* Collection Allocation and Deallocation */ \ - struct SNAME CMC_(PFX, _new)(struct CMC_DEF_FVAL(SNAME) * f_val); \ - struct SNAME CMC_(PFX, _new_custom)(struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_CALLBACKS_NAME * callbacks); \ - void CMC_(PFX, _free)(struct SNAME * _list_); \ - /* Customization of Allocation and Callbacks */ \ - void CMC_(PFX, _customize)(struct SNAME * _list_, \ - struct CMC_CALLBACKS_NAME * callbacks); \ - /* Collection Input and Output */ \ - bool CMC_(PFX, _push_front)(struct SNAME * _list_, V value); \ - bool CMC_(PFX, _push_at)(struct SNAME * _list_, V value, size_t index); \ - bool CMC_(PFX, _push_back)(struct SNAME * _list_, V value); \ - bool CMC_(PFX, _pop_front)(struct SNAME * _list_); \ - bool CMC_(PFX, _pop_at)(struct SNAME * _list_, size_t index); \ - bool CMC_(PFX, _pop_back)(struct SNAME * _list_); \ - /* Element Access */ \ - V CMC_(PFX, _front)(struct SNAME * _list_); \ - V CMC_(PFX, _get)(struct SNAME * _list_, size_t index); \ - V *CMC_(PFX, _get_ref)(struct SNAME * _list_, size_t index); \ - V CMC_(PFX, _back)(struct SNAME * _list_); \ - size_t CMC_(PFX, _index_of)(struct SNAME * _list_, V value, bool from_start); \ - /* Collection State */ \ - bool CMC_(PFX, _contains)(struct SNAME * _list_, V value); \ - bool CMC_(PFX, _empty)(struct SNAME * _list_); \ - bool CMC_(PFX, _full)(struct SNAME * _list_); \ - size_t CMC_(PFX, _count)(struct SNAME * _list_); \ - bool CMC_(PFX, _fits)(struct SNAME * _list_, size_t size); \ - size_t CMC_(PFX, _capacity)(struct SNAME * _list_); \ - int CMC_(PFX, _flag)(struct SNAME * _list_); \ - /* Collection Utility */ \ - struct SNAME CMC_(PFX, _copy_of)(struct SNAME * _list_); \ - bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_); - -/* ------------------------------------------------------------------------- - * Source - * ------------------------------------------------------------------------- */ -#define CMC_SAC_LIST_CORE_SOURCE_(PFX, SIZE, SNAME, V) \ -\ - /* Implementation Detail Functions */ \ - /* None */ \ -\ - struct SNAME CMC_(PFX, _new)(struct CMC_DEF_FVAL(SNAME) * f_val) \ - { \ - return CMC_(PFX, _new_custom)(f_val, NULL); \ - } \ -\ - struct SNAME CMC_(PFX, _new_custom)(struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - if (!f_val) \ - return (struct SNAME) { .flag = CMC_FLAG_ERROR, 0 }; \ -\ - struct SNAME _list_ = { 0 }; \ -\ - _list_.f_val = f_val; \ - CMC_CALLBACKS_ASSIGN(&_list_, callbacks); \ -\ - return _list_; \ - } \ -\ - void CMC_(PFX, _free)(struct SNAME * _list_) \ - { \ - if (_list_->f_val->free) \ - { \ - for (size_t i = 0; i < _list_->count; i++) \ - _list_->f_val->free(_list_->buffer[i]); \ - } \ -\ - memset(_list_, 0, sizeof(struct SNAME)); \ - } \ -\ - void CMC_(PFX, _customize)(struct SNAME * _list_, \ - struct CMC_CALLBACKS_NAME * callbacks) \ - { \ - CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \ -\ - CMC_CALLBACKS_ASSIGN(_list_, callbacks); \ -\ - _list_->flag = CMC_FLAG_OK; \ - } \ -\ - bool CMC_(PFX, _push_front)(struct SNAME * _list_, V value) \ - { \ - if (CMC_(PFX, _full)(_list_)) \ - {\ - _list_->flag = CMC_FLAG_FULL;\ - return false; \ - }\ -\ - if (!CMC_(PFX, _empty)(_list_)) \ - { \ - memmove(_list_->buffer + 1, _list_->buffer, _list_->count * sizeof(V)); \ - } \ -\ - _list_->buffer[0] = value; \ -\ - _list_->count++; \ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, create); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _push_at)(struct SNAME * _list_, V value, size_t index) \ - { \ - if (index > _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return false; \ - } \ -\ - if (CMC_(PFX, _full)(_list_)) \ - {\ - _list_->flag = CMC_FLAG_FULL;\ - return false; \ - }\ -\ - memmove(_list_->buffer + index + 1, _list_->buffer + index, (_list_->count - index) * sizeof(V)); \ -\ - _list_->buffer[index] = value; \ - _list_->count++; \ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, create); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _push_back)(struct SNAME * _list_, V value) \ - { \ - if (CMC_(PFX, _full)(_list_)) \ - {\ - _list_->flag = CMC_FLAG_FULL;\ - return false; \ - }\ -\ - _list_->buffer[_list_->count++] = value; \ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, create); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _pop_front)(struct SNAME * _list_) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - memmove(_list_->buffer, _list_->buffer + 1, (_list_->count - 1) * sizeof(V)); \ -\ - _list_->buffer[--_list_->count] = (V){ 0 }; \ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, delete); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _pop_at)(struct SNAME * _list_, size_t index) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return false; \ - } \ -\ - if (index >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return false; \ - } \ -\ - memmove(_list_->buffer + index, _list_->buffer + index + 1, (_list_->count - index - 1) * sizeof(V)); \ -\ - _list_->buffer[--_list_->count] = (V){ 0 }; \ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, delete); \ -\ - return true; \ - } \ -\ - bool CMC_(PFX, _pop_back)(struct SNAME * _list_) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - {\ - _list_->flag = CMC_FLAG_EMPTY; \ - return false; \ - }\ -\ - _list_->buffer[--_list_->count] = (V){ 0 }; \ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, delete); \ -\ - return true; \ - } \ -\ - V CMC_(PFX, _front)(struct SNAME * _list_) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ -\ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, read); \ -\ - return _list_->buffer[0]; \ - } \ -\ - V CMC_(PFX, _get)(struct SNAME * _list_, size_t index) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ -\ - if (index >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return (V){ 0 }; \ - } \ -\ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, read); \ -\ - return _list_->buffer[index]; \ - } \ -\ - V *CMC_(PFX, _get_ref)(struct SNAME * _list_, size_t index) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return NULL; \ - } \ -\ - if (index >= _list_->count) \ - { \ - _list_->flag = CMC_FLAG_RANGE; \ - return NULL; \ - } \ -\ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, read); \ -\ - return &(_list_->buffer[index]); \ - } \ -\ - V CMC_(PFX, _back)(struct SNAME * _list_) \ - { \ - if (CMC_(PFX, _empty)(_list_)) \ - { \ - _list_->flag = CMC_FLAG_EMPTY; \ - return (V){ 0 }; \ - } \ -\ - _list_->flag = CMC_FLAG_OK; \ -\ - CMC_CALLBACKS_CALL(_list_, read); \ -\ - return _list_->buffer[_list_->count - 1]; \ - } \ -\ - size_t CMC_(PFX, _index_of)(struct SNAME * _list_, V value, bool from_start) \ - { \ - _list_->flag = CMC_FLAG_OK; \ -\ - size_t result = _list_->count; \ -\ - if (from_start) \ - { \ - for (size_t i = 0; i < _list_->count; i++) \ - { \ - if (_list_->f_val->cmp(_list_->buffer[i], value) == 0) \ - { \ - result = i; \ - break; \ - } \ - } \ - } \ - else \ - { \ - for (size_t i = _list_->count; i > 0; i--) \ - { \ - if (_list_->f_val->cmp(_list_->buffer[i - 1], value) == 0) \ - { \ - result = i - 1; \ - break; \ - } \ - } \ - } \ -\ - CMC_CALLBACKS_CALL(_list_, read); \ -\ - return result; \ - } \ -\ - bool CMC_(PFX, _contains)(struct SNAME * _list_, V value) \ - { \ - _list_->flag = CMC_FLAG_OK; \ -\ - bool result = false; \ -\ - for (size_t i = 0; i < _list_->count; i++) \ - { \ - if (_list_->f_val->cmp(_list_->buffer[i], value) == 0) \ - { \ - result = true; \ - break; \ - } \ - } \ -\ - CMC_CALLBACKS_CALL(_list_, read); \ -\ - return result; \ - } \ -\ - bool CMC_(PFX, _empty)(struct SNAME * _list_) \ - { \ - return _list_->count == 0; \ - } \ -\ - bool CMC_(PFX, _full)(struct SNAME * _list_) \ - { \ - return _list_->count >= SIZE; \ - } \ -\ - size_t CMC_(PFX, _count)(struct SNAME * _list_) \ - { \ - return _list_->count; \ - } \ -\ - bool CMC_(PFX, _fits)(struct SNAME * _list_, size_t size) \ - { \ - return _list_->count + size <= SIZE; \ - } \ -\ - size_t CMC_(PFX, _capacity)(struct SNAME * _list_) \ - { \ - return SIZE; \ - } \ -\ - int CMC_(PFX, _flag)(struct SNAME * _list_) \ - { \ - return _list_->flag; \ - } \ -\ - struct SNAME CMC_(PFX, _copy_of)(struct SNAME * _list_) \ - { \ - struct SNAME result = CMC_(PFX, _new_custom)(_list_->f_val, NULL); \ -\ - CMC_CALLBACKS_ASSIGN(&result, _list_->callbacks); \ -\ - if (_list_->f_val->cpy) \ - { \ - for (size_t i = 0; i < _list_->count; i++) \ - result.buffer[i] = _list_->f_val->cpy(_list_->buffer[i]); \ - } \ - else \ - memcpy(result.buffer, _list_->buffer, sizeof(V) * _list_->count); \ -\ - result.count = _list_->count; \ - _list_->flag = CMC_FLAG_OK; \ -\ - return result; \ - } \ -\ - bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_) \ - { \ - _list1_->flag = CMC_FLAG_OK; \ - _list2_->flag = CMC_FLAG_OK; \ -\ - if (_list1_->count != _list2_->count) \ - return false; \ -\ - for (size_t i = 0; i < _list1_->count; i++) \ - { \ - if (0 != _list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i])) \ - return false; \ - } \ -\ - return true; \ - } - -#endif /* CMC_SAC_LIST_H */ diff --git a/tests/codecov.c b/tests/codecov.c deleted file mode 100644 index fd16011..0000000 --- a/tests/codecov.c +++ /dev/null @@ -1,140 +0,0 @@ -// Specifically used for code coverage - -#include -#include - -#include "macro_collections.h" - -#include "tst_cmc_bitset.h" -#include "tst_cmc_deque.h" -#include "tst_cmc_hashbidimap.h" -#include "tst_cmc_hashmap.h" -#include "tst_cmc_hashmultimap.h" -#include "tst_cmc_hashmultiset.h" -#include "tst_cmc_hashset.h" -#include "tst_cmc_heap.h" -#include "tst_cmc_intervalheap.h" -#include "tst_cmc_linkedlist.h" -#include "tst_cmc_list.h" -#include "tst_cmc_queue.h" -#include "tst_cmc_sortedlist.h" -#include "tst_cmc_stack.h" -#include "tst_cmc_treemap.h" -#include "tst_cmc_treeset.h" - -#include "tst_cmc_bitset.c" -#include "tst_cmc_deque.c" -#include "tst_cmc_hashbidimap.c" -#include "tst_cmc_hashmap.c" -#include "tst_cmc_hashmultimap.c" -#include "tst_cmc_hashmultiset.c" -#include "tst_cmc_hashset.c" -#include "tst_cmc_heap.c" -#include "tst_cmc_intervalheap.c" -#include "tst_cmc_linkedlist.c" -#include "tst_cmc_list.c" -#include "tst_cmc_queue.c" -#include "tst_cmc_sortedlist.c" -#include "tst_cmc_stack.c" -#include "tst_cmc_treemap.c" -#include "tst_cmc_treeset.c" - -#include "unt_cmc_bitset.h" -#include "unt_cmc_deque.h" -#include "unt_cmc_hashbidimap.h" -#include "unt_cmc_hashmap.h" -#include "unt_cmc_hashmultimap.h" -#include "unt_cmc_hashmultiset.h" -#include "unt_cmc_hashset.h" -#include "unt_cmc_heap.h" -#include "unt_cmc_intervalheap.h" -#include "unt_cmc_linkedlist.h" -#include "unt_cmc_list.h" -#include "unt_cmc_queue.h" -#include "unt_cmc_sortedlist.h" -#include "unt_cmc_stack.h" -#include "unt_cmc_treemap.h" -#include "unt_cmc_treeset.h" - -#include "unt_utl_foreach.h" - -#include "utl_assert.h" -#include "utl_timer.h" - -#include "utl.h" - -#define cmc_run(unit, unit_fails, test_fails) \ - do \ - { \ - uintmax_t f = unit(); \ - if (f != 0) \ - unit_fails += 1; \ - test_fails += f; \ - } while (0) - -int main(void) -{ - // clang-format off - printf(" +---------------------------------------------------------------+\n"); - printf(" | C Macro Collections Library |\n"); - printf(" | |\n"); - printf(" | Code Coverage Suite |\n"); - printf(" | |\n"); - printf(" | https://github.com/LeoVen/C-Macro-Collections |\n"); - printf(" | Leonardo Vencovsky (leonardo.vencovsky@gmail.com) |\n"); - printf(" +---------------------------------------------------------------+\n\n"); - // clang-format on - - struct cmc_timer timer; - - cmc_timer_start(timer); - uintmax_t tests = 0, units = 0; - - cmc_run(CMCBitSet, units, tests); - cmc_run(CMCBitSetIter, units, tests); - cmc_run(CMCDeque, units, tests); - cmc_run(CMCDequeIter, units, tests); - cmc_run(CMCHashBidiMap, units, tests); - cmc_run(CMCHashBidiMapIter, units, tests); - cmc_run(CMCHashMap, units, tests); - cmc_run(CMCHashMapIter, units, tests); - cmc_run(CMCHashMultiMap, units, tests); - cmc_run(CMCHashMultiMapIter, units, tests); - cmc_run(CMCHashMultiSet, units, tests); - cmc_run(CMCHashMultiSetIter, units, tests); - cmc_run(CMCHashSet, units, tests); - cmc_run(CMCHashSetIter, units, tests); - cmc_run(CMCHeap, units, tests); - cmc_run(CMCHeapIter, units, tests); - cmc_run(CMCIntervalHeap, units, tests); - cmc_run(CMCIntervalHeapIter, units, tests); - cmc_run(CMCLinkedList, units, tests); - cmc_run(CMCLinkedListIter, units, tests); - cmc_run(CMCList, units, tests); - cmc_run(CMCListIter, units, tests); - cmc_run(CMCQueue, units, tests); - cmc_run(CMCQueueIter, units, tests); - cmc_run(CMCSortedList, units, tests); - cmc_run(CMCSortedListIter, units, tests); - cmc_run(CMCStack, units, tests); - cmc_run(CMCStackIter, units, tests); - cmc_run(CMCTreeMap, units, tests); - cmc_run(CMCTreeMapIter, units, tests); - cmc_run(CMCTreeSet, units, tests); - cmc_run(CMCTreeSetIter, units, tests); - - cmc_run(ForEach, units, tests); - - cmc_timer_stop(timer); - - printf(" +---------------------------------------------------------------+\n"); - printf(" | SUMMARY |\n"); - printf(" +---------------------------------------------------------------+\n"); - printf(" | Total Units Failed : %25" PRIuMAX " units |\n", units); - printf(" | Total Tests Failed : %25" PRIuMAX " tests |\n", tests); - printf(" | Total Asserts Failed : %25" PRIuMAX " asserts |\n", cmc_assert_failed); - printf(" | Total Runtime : %25.0lf milliseconds |\n", timer.result); - printf(" +---------------------------------------------------------------+\n"); - - return tests; -} diff --git a/tests/include/tst_cmc_bitset.h b/tests/include/tst_cmc_bitset.h deleted file mode 100644 index 0c693e0..0000000 --- a/tests/include/tst_cmc_bitset.h +++ /dev/null @@ -1,44 +0,0 @@ - -#ifndef CMC_CMC_BITSET_TEST_H -#define CMC_CMC_BITSET_TEST_H - -#include "macro_collections.h" - -struct bitset -{ - cmc_bitset_word *buffer; - size_t capacity; - size_t count; - int flag; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct bitset_iter -{ - struct bitset *target; - size_t cursor; - _Bool start; - _Bool end; -}; -struct bitset *bs_new(size_t n_bits); -struct bitset *bs_new_custom(size_t n_bits, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -struct bitset bs_init(size_t n_bits); -struct bitset bs_init_custom(size_t n_bits, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -void bs_free(struct bitset *_bitset_); -void bs_release(struct bitset _bitset_); -void bs_customize(struct bitset *_bitset_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool bs_set(struct bitset *_bitset_, size_t bit_index); -_Bool bs_set_range(struct bitset *_bitset_, size_t from, size_t to); -_Bool bs_clear(struct bitset *_bitset_, size_t bit_index); -_Bool bs_clear_range(struct bitset *_bitset_, size_t from, size_t to); -_Bool bs_flip(struct bitset *_bitset_, size_t bit_index); -_Bool bs_flip_range(struct bitset *_bitset_, size_t from, size_t to); -_Bool bs_put(struct bitset *_bitset_, size_t bit_index, _Bool state); -_Bool bs_put_range(struct bitset *_bitset_, size_t from, size_t to, _Bool state); -_Bool bs_set_all(struct bitset *_bitset_); -_Bool bs_clear_all(struct bitset *_bitset_); -_Bool bs_flip_all(struct bitset *_bitset_); -_Bool bs_get(struct bitset *_bitset_, size_t bit_index); -_Bool bs_resize(struct bitset *_bitset_, size_t n_bits); - -#endif /* CMC_CMC_BITSET_TEST_H */ diff --git a/tests/include/tst_cmc_deque.h b/tests/include/tst_cmc_deque.h deleted file mode 100644 index b664e2a..0000000 --- a/tests/include/tst_cmc_deque.h +++ /dev/null @@ -1,78 +0,0 @@ - -#ifndef CMC_CMC_DEQUE_TEST_H -#define CMC_CMC_DEQUE_TEST_H - -#include "macro_collections.h" - -struct deque -{ - size_t *buffer; - size_t capacity; - size_t count; - size_t front; - size_t back; - int flag; - struct deque_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct deque_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct deque *d_new(size_t capacity, struct deque_fval *f_val); -struct deque *d_new_custom(size_t capacity, struct deque_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void d_clear(struct deque *_deque_); -void d_free(struct deque *_deque_); -void d_customize(struct deque *_deque_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool d_push_front(struct deque *_deque_, size_t value); -_Bool d_push_back(struct deque *_deque_, size_t value); -_Bool d_pop_front(struct deque *_deque_); -_Bool d_pop_back(struct deque *_deque_); -size_t d_front(struct deque *_deque_); -size_t d_back(struct deque *_deque_); -_Bool d_contains(struct deque *_deque_, size_t value); -_Bool d_empty(struct deque *_deque_); -_Bool d_full(struct deque *_deque_); -size_t d_count(struct deque *_deque_); -size_t d_capacity(struct deque *_deque_); -int d_flag(struct deque *_deque_); -_Bool d_resize(struct deque *_deque_, size_t capacity); -struct deque *d_copy_of(struct deque *_deque_); -_Bool d_equals(struct deque *_deque1_, struct deque *_deque2_); -struct deque d_init(size_t capacity, struct deque_fval *f_val); -struct deque d_init_custom(size_t capacity, struct deque_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void d_release(struct deque _deque_); -struct deque_iter -{ - struct deque *target; - size_t cursor; - size_t index; - _Bool start; - _Bool end; -}; -struct deque_iter d_iter_start(struct deque *target); -struct deque_iter d_iter_end(struct deque *target); -_Bool d_iter_at_start(struct deque_iter *iter); -_Bool d_iter_at_end(struct deque_iter *iter); -_Bool d_iter_to_start(struct deque_iter *iter); -_Bool d_iter_to_end(struct deque_iter *iter); -_Bool d_iter_next(struct deque_iter *iter); -_Bool d_iter_prev(struct deque_iter *iter); -_Bool d_iter_advance(struct deque_iter *iter, size_t steps); -_Bool d_iter_rewind(struct deque_iter *iter, size_t steps); -_Bool d_iter_go_to(struct deque_iter *iter, size_t index); -size_t d_iter_value(struct deque_iter *iter); -size_t *d_iter_rvalue(struct deque_iter *iter); -size_t d_iter_index(struct deque_iter *iter); -_Bool d_to_string(struct deque *_deque_, FILE *fptr); -_Bool d_print(struct deque *_deque_, FILE *fptr, const char *start, const char *separator, const char *end); - -#endif /* CMC_CMC_DEQUE_TEST_H */ diff --git a/tests/include/tst_cmc_hashbidimap.h b/tests/include/tst_cmc_hashbidimap.h deleted file mode 100644 index c574437..0000000 --- a/tests/include/tst_cmc_hashbidimap.h +++ /dev/null @@ -1,101 +0,0 @@ - -#ifndef CMC_CMC_HASHBIDIMAP_TEST_H -#define CMC_CMC_HASHBIDIMAP_TEST_H - -#include "macro_collections.h" - -struct hashbidimap -{ - struct hashbidimap_entry *(*buffer)[2]; - size_t capacity; - size_t count; - double load; - int flag; - struct hashbidimap_fkey *f_key; - struct hashbidimap_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; - struct hashbidimap_iter (*it_start)(struct hashbidimap *); - struct hashbidimap_iter (*it_end)(struct hashbidimap *); -}; -struct hashbidimap_entry -{ - size_t key; - size_t value; - size_t dist[2]; - struct hashbidimap_entry **ref[2]; -}; -struct hashbidimap_fkey -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct hashbidimap_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct hashbidimap_iter -{ - struct hashbidimap *target; - size_t cursor; - size_t index; - size_t first; - size_t last; - _Bool start; - _Bool end; -}; -struct hashbidimap *hbm_new(size_t capacity, double load, struct hashbidimap_fkey *f_key, - struct hashbidimap_fval *f_val); -struct hashbidimap *hbm_new_custom(size_t capacity, double load, struct hashbidimap_fkey *f_key, - struct hashbidimap_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void hbm_clear(struct hashbidimap *_map_); -void hbm_free(struct hashbidimap *_map_); -void hbm_customize(struct hashbidimap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool hbm_insert(struct hashbidimap *_map_, size_t key, size_t value); -_Bool hbm_update_key(struct hashbidimap *_map_, size_t val, size_t new_key); -_Bool hbm_update_val(struct hashbidimap *_map_, size_t key, size_t new_val); -_Bool hbm_remove_by_key(struct hashbidimap *_map_, size_t key, size_t *out_key, size_t *out_val); -_Bool hbm_remove_by_val(struct hashbidimap *_map_, size_t val, size_t *out_key, size_t *out_val); -size_t hbm_get_key(struct hashbidimap *_map_, size_t val); -size_t hbm_get_val(struct hashbidimap *_map_, size_t key); -_Bool hbm_contains_key(struct hashbidimap *_map_, size_t key); -_Bool hbm_contains_val(struct hashbidimap *_map_, size_t val); -_Bool hbm_empty(struct hashbidimap *_map_); -_Bool hbm_full(struct hashbidimap *_map_); -size_t hbm_count(struct hashbidimap *_map_); -size_t hbm_capacity(struct hashbidimap *_map_); -double hbm_load(struct hashbidimap *_map_); -int hbm_flag(struct hashbidimap *_map_); -_Bool hbm_resize(struct hashbidimap *_map_, size_t capacity); -struct hashbidimap *hbm_copy_of(struct hashbidimap *_map_); -_Bool hbm_equals(struct hashbidimap *_map1_, struct hashbidimap *_map2_); -struct hashbidimap_iter *hbm_iter_new(struct hashbidimap *target); -void hbm_iter_free(struct hashbidimap_iter *iter); -void hbm_iter_init(struct hashbidimap_iter *iter, struct hashbidimap *target); -_Bool hbm_iter_start(struct hashbidimap_iter *iter); -_Bool hbm_iter_end(struct hashbidimap_iter *iter); -void hbm_iter_to_start(struct hashbidimap_iter *iter); -void hbm_iter_to_end(struct hashbidimap_iter *iter); -_Bool hbm_iter_next(struct hashbidimap_iter *iter); -_Bool hbm_iter_prev(struct hashbidimap_iter *iter); -_Bool hbm_iter_advance(struct hashbidimap_iter *iter, size_t steps); -_Bool hbm_iter_rewind(struct hashbidimap_iter *iter, size_t steps); -_Bool hbm_iter_go_to(struct hashbidimap_iter *iter, size_t index); -size_t hbm_iter_key(struct hashbidimap_iter *iter); -size_t hbm_iter_value(struct hashbidimap_iter *iter); -size_t hbm_iter_index(struct hashbidimap_iter *iter); -_Bool hbm_to_string(struct hashbidimap *_map_, FILE *fptr); -_Bool hbm_print(struct hashbidimap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, - const char *key_val_sep); - -#endif /* CMC_CMC_HASHBIDIMAP_TEST_H */ diff --git a/tests/include/tst_cmc_hashmap.h b/tests/include/tst_cmc_hashmap.h deleted file mode 100644 index 5bb61eb..0000000 --- a/tests/include/tst_cmc_hashmap.h +++ /dev/null @@ -1,100 +0,0 @@ - -#ifndef CMC_CMC_HASHMAP_TEST_H -#define CMC_CMC_HASHMAP_TEST_H - -#include "macro_collections.h" - -struct hashmap -{ - struct hashmap_entry *buffer; - size_t capacity; - size_t count; - double load; - int flag; - struct hashmap_fkey *f_key; - struct hashmap_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct hashmap_entry -{ - size_t key; - size_t value; - size_t dist; - enum cmc_entry_state state; -}; -struct hashmap_fkey -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct hashmap_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct hashmap *hm_new(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val); -struct hashmap *hm_new_custom(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val, - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -void hm_clear(struct hashmap *_map_); -void hm_free(struct hashmap *_map_); -void hm_customize(struct hashmap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool hm_insert(struct hashmap *_map_, size_t key, size_t value); -_Bool hm_update(struct hashmap *_map_, size_t key, size_t new_value, size_t *old_value); -_Bool hm_remove(struct hashmap *_map_, size_t key, size_t *out_value); -_Bool hm_max(struct hashmap *_map_, size_t *key, size_t *value); -_Bool hm_min(struct hashmap *_map_, size_t *key, size_t *value); -size_t hm_get(struct hashmap *_map_, size_t key); -size_t *hm_get_ref(struct hashmap *_map_, size_t key); -_Bool hm_contains(struct hashmap *_map_, size_t key); -_Bool hm_empty(struct hashmap *_map_); -_Bool hm_full(struct hashmap *_map_); -size_t hm_count(struct hashmap *_map_); -size_t hm_capacity(struct hashmap *_map_); -double hm_load(struct hashmap *_map_); -int hm_flag(struct hashmap *_map_); -_Bool hm_resize(struct hashmap *_map_, size_t capacity); -struct hashmap *hm_copy_of(struct hashmap *_map_); -_Bool hm_equals(struct hashmap *_map1_, struct hashmap *_map2_); -struct hashmap hm_init(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val); -struct hashmap hm_init_custom(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val, - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -void hm_release(struct hashmap _map_); -struct hashmap_iter -{ - struct hashmap *target; - size_t cursor; - size_t index; - size_t first; - size_t last; - _Bool start; - _Bool end; -}; -struct hashmap_iter hm_iter_start(struct hashmap *target); -struct hashmap_iter hm_iter_end(struct hashmap *target); -_Bool hm_iter_at_start(struct hashmap_iter *iter); -_Bool hm_iter_at_end(struct hashmap_iter *iter); -_Bool hm_iter_to_start(struct hashmap_iter *iter); -_Bool hm_iter_to_end(struct hashmap_iter *iter); -_Bool hm_iter_next(struct hashmap_iter *iter); -_Bool hm_iter_prev(struct hashmap_iter *iter); -_Bool hm_iter_advance(struct hashmap_iter *iter, size_t steps); -_Bool hm_iter_rewind(struct hashmap_iter *iter, size_t steps); -_Bool hm_iter_go_to(struct hashmap_iter *iter, size_t index); -size_t hm_iter_key(struct hashmap_iter *iter); -size_t hm_iter_value(struct hashmap_iter *iter); -size_t *hm_iter_rvalue(struct hashmap_iter *iter); -size_t hm_iter_index(struct hashmap_iter *iter); -_Bool hm_to_string(struct hashmap *_map_, FILE *fptr); -_Bool hm_print(struct hashmap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, - const char *key_val_sep); - -#endif /* CMC_CMC_HASHMAP_TEST_H */ diff --git a/tests/include/tst_cmc_hashmultimap.h b/tests/include/tst_cmc_hashmultimap.h deleted file mode 100644 index 7b44266..0000000 --- a/tests/include/tst_cmc_hashmultimap.h +++ /dev/null @@ -1,102 +0,0 @@ - -#ifndef CMC_CMC_HASHMULTIMAP_TEST_H -#define CMC_CMC_HASHMULTIMAP_TEST_H - -#include "macro_collections.h" - -struct hashmultimap -{ - struct hashmultimap_entry *(*buffer)[2]; - size_t capacity; - size_t count; - double load; - int flag; - struct hashmultimap_fkey *f_key; - struct hashmultimap_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct hashmultimap_entry -{ - size_t key; - size_t value; - struct hashmultimap_entry *next; - struct hashmultimap_entry *prev; -}; -struct hashmultimap_fkey -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct hashmultimap_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct hashmultimap *hmm_new(size_t capacity, double load, struct hashmultimap_fkey *f_key, - struct hashmultimap_fval *f_val); -struct hashmultimap *hmm_new_custom(size_t capacity, double load, struct hashmultimap_fkey *f_key, - struct hashmultimap_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void hmm_clear(struct hashmultimap *_map_); -void hmm_free(struct hashmultimap *_map_); -void hmm_customize(struct hashmultimap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool hmm_insert(struct hashmultimap *_map_, size_t key, size_t value); -_Bool hmm_update(struct hashmultimap *_map_, size_t key, size_t new_value, size_t *old_value); -size_t hmm_update_all(struct hashmultimap *_map_, size_t key, size_t new_value, size_t **old_values); -_Bool hmm_remove(struct hashmultimap *_map_, size_t key, size_t *out_value); -size_t hmm_remove_all(struct hashmultimap *_map_, size_t key, size_t **out_values); -_Bool hmm_max(struct hashmultimap *_map_, size_t *key, size_t *value); -_Bool hmm_min(struct hashmultimap *_map_, size_t *key, size_t *value); -size_t hmm_get(struct hashmultimap *_map_, size_t key); -size_t *hmm_get_ref(struct hashmultimap *_map_, size_t key); -_Bool hmm_contains(struct hashmultimap *_map_, size_t key); -_Bool hmm_empty(struct hashmultimap *_map_); -_Bool hmm_full(struct hashmultimap *_map_); -size_t hmm_count(struct hashmultimap *_map_); -size_t hmm_key_count(struct hashmultimap *_map_, size_t key); -size_t hmm_capacity(struct hashmultimap *_map_); -double hmm_load(struct hashmultimap *_map_); -int hmm_flag(struct hashmultimap *_map_); -_Bool hmm_resize(struct hashmultimap *_map_, size_t capacity); -struct hashmultimap *hmm_copy_of(struct hashmultimap *_map_); -_Bool hmm_equals(struct hashmultimap *_map1_, struct hashmultimap *_map2_); -struct hashmultimap_iter -{ - struct hashmultimap *target; - struct hashmultimap_entry *curr_entry; - size_t cursor; - size_t index; - size_t first; - size_t last; - _Bool start; - _Bool end; -}; -struct hashmultimap_iter hmm_iter_start(struct hashmultimap *target); -struct hashmultimap_iter hmm_iter_end(struct hashmultimap *target); -_Bool hmm_iter_at_start(struct hashmultimap_iter *iter); -_Bool hmm_iter_at_end(struct hashmultimap_iter *iter); -_Bool hmm_iter_to_start(struct hashmultimap_iter *iter); -_Bool hmm_iter_to_end(struct hashmultimap_iter *iter); -_Bool hmm_iter_next(struct hashmultimap_iter *iter); -_Bool hmm_iter_prev(struct hashmultimap_iter *iter); -_Bool hmm_iter_advance(struct hashmultimap_iter *iter, size_t steps); -_Bool hmm_iter_rewind(struct hashmultimap_iter *iter, size_t steps); -_Bool hmm_iter_go_to(struct hashmultimap_iter *iter, size_t index); -size_t hmm_iter_key(struct hashmultimap_iter *iter); -size_t hmm_iter_value(struct hashmultimap_iter *iter); -size_t *hmm_iter_rvalue(struct hashmultimap_iter *iter); -size_t hmm_iter_index(struct hashmultimap_iter *iter); -_Bool hmm_to_string(struct hashmultimap *_map_, FILE *fptr); -_Bool hmm_print(struct hashmultimap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, - const char *key_val_sep); - -#endif /* CMC_CMC_HASHMULTIMAP_TEST_H */ diff --git a/tests/include/tst_cmc_hashmultiset.h b/tests/include/tst_cmc_hashmultiset.h deleted file mode 100644 index 6ab4627..0000000 --- a/tests/include/tst_cmc_hashmultiset.h +++ /dev/null @@ -1,98 +0,0 @@ - -#ifndef CMC_CMC_HASHMULTISET_TEST_H -#define CMC_CMC_HASHMULTISET_TEST_H - -#include "macro_collections.h" - -struct hashmultiset -{ - struct hashmultiset_entry *buffer; - size_t capacity; - size_t count; - size_t cardinality; - double load; - int flag; - struct hashmultiset_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct hashmultiset_entry -{ - size_t value; - size_t multiplicity; - size_t dist; - enum cmc_entry_state state; -}; -struct hashmultiset_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct hashmultiset *hms_new(size_t capacity, double load, struct hashmultiset_fval *f_val); -struct hashmultiset *hms_new_custom(size_t capacity, double load, struct hashmultiset_fval *f_val, - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -void hms_clear(struct hashmultiset *_set_); -void hms_free(struct hashmultiset *_set_); -void hms_customize(struct hashmultiset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool hms_insert(struct hashmultiset *_set_, size_t value); -_Bool hms_insert_many(struct hashmultiset *_set_, size_t value, size_t count); -_Bool hms_update(struct hashmultiset *_set_, size_t value, size_t multiplicity); -_Bool hms_remove(struct hashmultiset *_set_, size_t value); -size_t hms_remove_all(struct hashmultiset *_set_, size_t value); -_Bool hms_max(struct hashmultiset *_set_, size_t *value); -_Bool hms_min(struct hashmultiset *_set_, size_t *value); -size_t hms_multiplicity_of(struct hashmultiset *_set_, size_t value); -_Bool hms_contains(struct hashmultiset *_set_, size_t value); -_Bool hms_empty(struct hashmultiset *_set_); -_Bool hms_full(struct hashmultiset *_set_); -size_t hms_count(struct hashmultiset *_set_); -size_t hms_cardinality(struct hashmultiset *_set_); -size_t hms_capacity(struct hashmultiset *_set_); -double hms_load(struct hashmultiset *_set_); -int hms_flag(struct hashmultiset *_set_); -_Bool hms_resize(struct hashmultiset *_set_, size_t capacity); -struct hashmultiset *hms_copy_of(struct hashmultiset *_set_); -_Bool hms_equals(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -struct hashmultiset_iter -{ - struct hashmultiset *target; - size_t cursor; - size_t index; - size_t first; - size_t last; - _Bool start; - _Bool end; -}; -struct hashmultiset_iter hms_iter_start(struct hashmultiset *target); -struct hashmultiset_iter hms_iter_end(struct hashmultiset *target); -_Bool hms_iter_at_start(struct hashmultiset_iter *iter); -_Bool hms_iter_at_end(struct hashmultiset_iter *iter); -_Bool hms_iter_to_start(struct hashmultiset_iter *iter); -_Bool hms_iter_to_end(struct hashmultiset_iter *iter); -_Bool hms_iter_next(struct hashmultiset_iter *iter); -_Bool hms_iter_prev(struct hashmultiset_iter *iter); -_Bool hms_iter_advance(struct hashmultiset_iter *iter, size_t steps); -_Bool hms_iter_rewind(struct hashmultiset_iter *iter, size_t steps); -_Bool hms_iter_go_to(struct hashmultiset_iter *iter, size_t index); -size_t hms_iter_value(struct hashmultiset_iter *iter); -size_t hms_iter_multiplicity(struct hashmultiset_iter *iter); -size_t hms_iter_index(struct hashmultiset_iter *iter); -struct hashmultiset *hms_union(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -struct hashmultiset *hms_intersection(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -struct hashmultiset *hms_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -struct hashmultiset *hms_summation(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -struct hashmultiset *hms_symmetric_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -_Bool hms_is_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -_Bool hms_is_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -_Bool hms_is_proper_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -_Bool hms_is_proper_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -_Bool hms_is_disjointset(struct hashmultiset *_set1_, struct hashmultiset *_set2_); -_Bool hms_to_string(struct hashmultiset *_set_, FILE *fptr); -_Bool hms_print(struct hashmultiset *_set_, FILE *fptr, const char *start, const char *separator, const char *end, - const char *key_val_sep); - -#endif /* CMC_CMC_HASHMULTISET_TEST_H */ diff --git a/tests/include/tst_cmc_hashset.h b/tests/include/tst_cmc_hashset.h deleted file mode 100644 index a9ab75c..0000000 --- a/tests/include/tst_cmc_hashset.h +++ /dev/null @@ -1,88 +0,0 @@ - -#ifndef CMC_CMC_HASHSET_TEST_H -#define CMC_CMC_HASHSET_TEST_H - -#include "macro_collections.h" - -struct hashset -{ - struct hashset_entry *buffer; - size_t capacity; - size_t count; - double load; - int flag; - struct hashset_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct hashset_entry -{ - size_t value; - size_t dist; - enum cmc_entry_state state; -}; -struct hashset_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct hashset *hs_new(size_t capacity, double load, struct hashset_fval *f_val); -struct hashset *hs_new_custom(size_t capacity, double load, struct hashset_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void hs_clear(struct hashset *_set_); -void hs_free(struct hashset *_set_); -void hs_customize(struct hashset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool hs_insert(struct hashset *_set_, size_t value); -_Bool hs_remove(struct hashset *_set_, size_t value); -_Bool hs_max(struct hashset *_set_, size_t *value); -_Bool hs_min(struct hashset *_set_, size_t *value); -_Bool hs_contains(struct hashset *_set_, size_t value); -_Bool hs_empty(struct hashset *_set_); -_Bool hs_full(struct hashset *_set_); -size_t hs_count(struct hashset *_set_); -size_t hs_capacity(struct hashset *_set_); -double hs_load(struct hashset *_set_); -int hs_flag(struct hashset *_set_); -_Bool hs_resize(struct hashset *_set_, size_t capacity); -struct hashset *hs_copy_of(struct hashset *_set_); -_Bool hs_equals(struct hashset *_set1_, struct hashset *_set2_); -struct hashset_iter -{ - struct hashset *target; - size_t cursor; - size_t index; - size_t first; - size_t last; - _Bool start; - _Bool end; -}; -struct hashset_iter hs_iter_start(struct hashset *target); -struct hashset_iter hs_iter_end(struct hashset *target); -_Bool hs_iter_at_start(struct hashset_iter *iter); -_Bool hs_iter_at_end(struct hashset_iter *iter); -_Bool hs_iter_to_start(struct hashset_iter *iter); -_Bool hs_iter_to_end(struct hashset_iter *iter); -_Bool hs_iter_next(struct hashset_iter *iter); -_Bool hs_iter_prev(struct hashset_iter *iter); -_Bool hs_iter_advance(struct hashset_iter *iter, size_t steps); -_Bool hs_iter_rewind(struct hashset_iter *iter, size_t steps); -_Bool hs_iter_go_to(struct hashset_iter *iter, size_t index); -size_t hs_iter_value(struct hashset_iter *iter); -size_t hs_iter_index(struct hashset_iter *iter); -struct hashset *hs_union(struct hashset *_set1_, struct hashset *_set2_); -struct hashset *hs_intersection(struct hashset *_set1_, struct hashset *_set2_); -struct hashset *hs_difference(struct hashset *_set1_, struct hashset *_set2_); -struct hashset *hs_symmetric_difference(struct hashset *_set1_, struct hashset *_set2_); -_Bool hs_is_subset(struct hashset *_set1_, struct hashset *_set2_); -_Bool hs_is_superset(struct hashset *_set1_, struct hashset *_set2_); -_Bool hs_is_proper_subset(struct hashset *_set1_, struct hashset *_set2_); -_Bool hs_is_proper_superset(struct hashset *_set1_, struct hashset *_set2_); -_Bool hs_is_disjointset(struct hashset *_set1_, struct hashset *_set2_); -_Bool hs_to_string(struct hashset *_set_, FILE *fptr); -_Bool hs_print(struct hashset *_set_, FILE *fptr, const char *start, const char *separator, const char *end); - -#endif /* CMC_CMC_HASHSET_TEST_H */ diff --git a/tests/include/tst_cmc_heap.h b/tests/include/tst_cmc_heap.h deleted file mode 100644 index 8b062f1..0000000 --- a/tests/include/tst_cmc_heap.h +++ /dev/null @@ -1,68 +0,0 @@ - -#ifndef CMC_CMC_HEAP_TEST_H -#define CMC_CMC_HEAP_TEST_H - -#include "macro_collections.h" - -struct heap -{ - size_t *buffer; - size_t capacity; - size_t count; - enum cmc_heap_order HO; - int flag; - struct heap_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct heap_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct heap *h_new(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val); -struct heap *h_new_custom(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val, - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -void h_clear(struct heap *_heap_); -void h_free(struct heap *_heap_); -void h_customize(struct heap *_heap_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool h_insert(struct heap *_heap_, size_t value); -_Bool h_remove(struct heap *_heap_); -size_t h_peek(struct heap *_heap_); -_Bool h_contains(struct heap *_heap_, size_t value); -_Bool h_empty(struct heap *_heap_); -_Bool h_full(struct heap *_heap_); -size_t h_count(struct heap *_heap_); -size_t h_capacity(struct heap *_heap_); -int h_flag(struct heap *_heap_); -_Bool h_resize(struct heap *_heap_, size_t capacity); -struct heap *h_copy_of(struct heap *_heap_); -_Bool h_equals(struct heap *_heap1_, struct heap *_heap2_); -struct heap_iter -{ - struct heap *target; - size_t cursor; - _Bool start; - _Bool end; -}; -struct heap_iter h_iter_start(struct heap *target); -struct heap_iter h_iter_end(struct heap *target); -_Bool h_iter_at_start(struct heap_iter *iter); -_Bool h_iter_at_end(struct heap_iter *iter); -_Bool h_iter_to_start(struct heap_iter *iter); -_Bool h_iter_to_end(struct heap_iter *iter); -_Bool h_iter_next(struct heap_iter *iter); -_Bool h_iter_prev(struct heap_iter *iter); -_Bool h_iter_advance(struct heap_iter *iter, size_t steps); -_Bool h_iter_rewind(struct heap_iter *iter, size_t steps); -_Bool h_iter_go_to(struct heap_iter *iter, size_t index); -size_t h_iter_value(struct heap_iter *iter); -size_t h_iter_index(struct heap_iter *iter); -_Bool h_to_string(struct heap *_heap_, FILE *fptr); -_Bool h_print(struct heap *_heap_, FILE *fptr, const char *start, const char *separator, const char *end); - -#endif /* CMC_CMC_HEAP_TEST_H */ diff --git a/tests/include/tst_cmc_intervalheap.h b/tests/include/tst_cmc_intervalheap.h deleted file mode 100644 index 5bc4fb2..0000000 --- a/tests/include/tst_cmc_intervalheap.h +++ /dev/null @@ -1,72 +0,0 @@ - -#ifndef CMC_CMC_INTERVALHEAP_TEST_H -#define CMC_CMC_INTERVALHEAP_TEST_H - -#include "macro_collections.h" - -struct intervalheap -{ - size_t (*buffer)[2]; - size_t capacity; - size_t size; - size_t count; - int flag; - struct intervalheap_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct intervalheap_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct intervalheap *ih_new(size_t capacity, struct intervalheap_fval *f_val); -struct intervalheap *ih_new_custom(size_t capacity, struct intervalheap_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void ih_clear(struct intervalheap *_heap_); -void ih_free(struct intervalheap *_heap_); -void ih_customize(struct intervalheap *_heap_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool ih_insert(struct intervalheap *_heap_, size_t value); -_Bool ih_remove_max(struct intervalheap *_heap_); -_Bool ih_remove_min(struct intervalheap *_heap_); -_Bool ih_update_max(struct intervalheap *_heap_, size_t value); -_Bool ih_update_min(struct intervalheap *_heap_, size_t value); -size_t ih_max(struct intervalheap *_heap_); -size_t ih_min(struct intervalheap *_heap_); -_Bool ih_contains(struct intervalheap *_heap_, size_t value); -_Bool ih_empty(struct intervalheap *_heap_); -_Bool ih_full(struct intervalheap *_heap_); -size_t ih_count(struct intervalheap *_heap_); -size_t ih_capacity(struct intervalheap *_heap_); -int ih_flag(struct intervalheap *_heap_); -_Bool ih_resize(struct intervalheap *_heap_, size_t capacity); -struct intervalheap *ih_copy_of(struct intervalheap *_heap_); -_Bool ih_equals(struct intervalheap *_heap1_, struct intervalheap *_heap2_); -struct intervalheap_iter -{ - struct intervalheap *target; - size_t cursor; - _Bool start; - _Bool end; -}; -struct intervalheap_iter ih_iter_start(struct intervalheap *target); -struct intervalheap_iter ih_iter_end(struct intervalheap *target); -_Bool ih_iter_at_start(struct intervalheap_iter *iter); -_Bool ih_iter_at_end(struct intervalheap_iter *iter); -_Bool ih_iter_to_start(struct intervalheap_iter *iter); -_Bool ih_iter_to_end(struct intervalheap_iter *iter); -_Bool ih_iter_next(struct intervalheap_iter *iter); -_Bool ih_iter_prev(struct intervalheap_iter *iter); -_Bool ih_iter_advance(struct intervalheap_iter *iter, size_t steps); -_Bool ih_iter_rewind(struct intervalheap_iter *iter, size_t steps); -_Bool ih_iter_go_to(struct intervalheap_iter *iter, size_t index); -size_t ih_iter_value(struct intervalheap_iter *iter); -size_t ih_iter_index(struct intervalheap_iter *iter); -_Bool ih_to_string(struct intervalheap *_heap_, FILE *fptr); -_Bool ih_print(struct intervalheap *_heap_, FILE *fptr, const char *start, const char *separator, const char *end); - -#endif /* CMC_CMC_INTERVALHEAP_TEST_H */ diff --git a/tests/include/tst_cmc_linkedlist.h b/tests/include/tst_cmc_linkedlist.h deleted file mode 100644 index c06925d..0000000 --- a/tests/include/tst_cmc_linkedlist.h +++ /dev/null @@ -1,92 +0,0 @@ - -#ifndef CMC_CMC_LINKEDLIST_TEST_H -#define CMC_CMC_LINKEDLIST_TEST_H - -#include "macro_collections.h" - -struct linkedlist -{ - struct linkedlist_node *head; - struct linkedlist_node *tail; - size_t count; - int flag; - struct linkedlist_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct linkedlist_node -{ - size_t value; - struct linkedlist_node *next; - struct linkedlist_node *prev; -}; -struct linkedlist_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct linkedlist *ll_new(struct linkedlist_fval *f_val); -struct linkedlist *ll_new_custom(struct linkedlist_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void ll_clear(struct linkedlist *_list_); -void ll_free(struct linkedlist *_list_); -void ll_customize(struct linkedlist *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool ll_push_front(struct linkedlist *_list_, size_t value); -_Bool ll_push_at(struct linkedlist *_list_, size_t value, size_t index); -_Bool ll_push_back(struct linkedlist *_list_, size_t value); -_Bool ll_pop_front(struct linkedlist *_list_); -_Bool ll_pop_at(struct linkedlist *_list_, size_t index); -_Bool ll_pop_back(struct linkedlist *_list_); -size_t ll_front(struct linkedlist *_list_); -size_t ll_get(struct linkedlist *_list_, size_t index); -size_t *ll_get_ref(struct linkedlist *_list_, size_t index); -size_t ll_back(struct linkedlist *_list_); -_Bool ll_contains(struct linkedlist *_list_, size_t value); -_Bool ll_empty(struct linkedlist *_list_); -size_t ll_count(struct linkedlist *_list_); -int ll_flag(struct linkedlist *_list_); -struct linkedlist *ll_copy_of(struct linkedlist *_list_); -_Bool ll_equals(struct linkedlist *_list1_, struct linkedlist *_list2_); -struct linkedlist_iter -{ - struct linkedlist *target; - struct linkedlist_node *cursor; - size_t index; - _Bool start; - _Bool end; -}; -struct linkedlist_iter ll_iter_start(struct linkedlist *target); -struct linkedlist_iter ll_iter_end(struct linkedlist *target); -_Bool ll_iter_at_start(struct linkedlist_iter *iter); -_Bool ll_iter_at_end(struct linkedlist_iter *iter); -_Bool ll_iter_to_start(struct linkedlist_iter *iter); -_Bool ll_iter_to_end(struct linkedlist_iter *iter); -_Bool ll_iter_next(struct linkedlist_iter *iter); -_Bool ll_iter_prev(struct linkedlist_iter *iter); -_Bool ll_iter_advance(struct linkedlist_iter *iter, size_t steps); -_Bool ll_iter_rewind(struct linkedlist_iter *iter, size_t steps); -_Bool ll_iter_go_to(struct linkedlist_iter *iter, size_t index); -size_t ll_iter_value(struct linkedlist_iter *iter); -size_t *ll_iter_rvalue(struct linkedlist_iter *iter); -size_t ll_iter_index(struct linkedlist_iter *iter); -struct linkedlist_node *ll_iter_node(struct linkedlist_iter *iter); -struct linkedlist_node *ll_new_node(struct linkedlist *_list_, size_t value); -void ll_free_node(struct linkedlist *_list_, struct linkedlist_node *_node_); -struct linkedlist_node *ll_head(struct linkedlist *_list_); -struct linkedlist_node *ll_get_node(struct linkedlist *_list_, size_t index); -struct linkedlist_node *ll_tail(struct linkedlist *_list_); -_Bool ll_add_next(struct linkedlist *_owner_, struct linkedlist_node *_node_, size_t value); -_Bool ll_add_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_, size_t value); -_Bool ll_del_next(struct linkedlist *_owner_, struct linkedlist_node *_node_); -_Bool ll_del_curr(struct linkedlist *_owner_, struct linkedlist_node *_node_); -_Bool ll_del_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_); -struct linkedlist_node *ll_next_node(struct linkedlist_node *_node_); -struct linkedlist_node *ll_prev_node(struct linkedlist_node *_node_); -_Bool ll_to_string(struct linkedlist *_list_, FILE *fptr); -_Bool ll_print(struct linkedlist *_list_, FILE *fptr, const char *start, const char *separator, const char *end); - -#endif /* CMC_CMC_LINKEDLIST_TEST_H */ diff --git a/tests/include/tst_cmc_list.h b/tests/include/tst_cmc_list.h deleted file mode 100644 index 3a1043d..0000000 --- a/tests/include/tst_cmc_list.h +++ /dev/null @@ -1,82 +0,0 @@ - -#ifndef CMC_CMC_LIST_TEST_H -#define CMC_CMC_LIST_TEST_H - -#include "macro_collections.h" - -struct list -{ - size_t *buffer; - size_t capacity; - size_t count; - int flag; - struct list_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct list_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct list *l_new(size_t capacity, struct list_fval *f_val); -struct list *l_new_custom(size_t capacity, struct list_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void l_clear(struct list *_list_); -void l_free(struct list *_list_); -void l_customize(struct list *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool l_push_front(struct list *_list_, size_t value); -_Bool l_push_at(struct list *_list_, size_t value, size_t index); -_Bool l_push_back(struct list *_list_, size_t value); -_Bool l_pop_front(struct list *_list_); -_Bool l_pop_at(struct list *_list_, size_t index); -_Bool l_pop_back(struct list *_list_); -size_t l_front(struct list *_list_); -size_t l_get(struct list *_list_, size_t index); -size_t *l_get_ref(struct list *_list_, size_t index); -size_t l_back(struct list *_list_); -size_t l_index_of(struct list *_list_, size_t value, _Bool from_start); -_Bool l_contains(struct list *_list_, size_t value); -_Bool l_empty(struct list *_list_); -_Bool l_full(struct list *_list_); -size_t l_count(struct list *_list_); -_Bool l_fits(struct list *_list_, size_t size); -size_t l_capacity(struct list *_list_); -int l_flag(struct list *_list_); -_Bool l_resize(struct list *_list_, size_t capacity); -struct list *l_copy_of(struct list *_list_); -_Bool l_equals(struct list *_list1_, struct list *_list2_); -struct list_iter -{ - struct list *target; - size_t cursor; - _Bool start; - _Bool end; -}; -struct list_iter l_iter_start(struct list *target); -struct list_iter l_iter_end(struct list *target); -_Bool l_iter_at_start(struct list_iter *iter); -_Bool l_iter_at_end(struct list_iter *iter); -_Bool l_iter_to_start(struct list_iter *iter); -_Bool l_iter_to_end(struct list_iter *iter); -_Bool l_iter_next(struct list_iter *iter); -_Bool l_iter_prev(struct list_iter *iter); -_Bool l_iter_advance(struct list_iter *iter, size_t steps); -_Bool l_iter_rewind(struct list_iter *iter, size_t steps); -_Bool l_iter_go_to(struct list_iter *iter, size_t index); -size_t l_iter_value(struct list_iter *iter); -size_t *l_iter_rvalue(struct list_iter *iter); -size_t l_iter_index(struct list_iter *iter); -_Bool l_seq_push_front(struct list *_list_, size_t *values, size_t size); -_Bool l_seq_push_at(struct list *_list_, size_t *values, size_t size, size_t index); -_Bool l_seq_push_back(struct list *_list_, size_t *values, size_t size); -_Bool l_seq_pop_at(struct list *_list_, size_t from, size_t to); -struct list *l_seq_sublist(struct list *_list_, size_t from, size_t to); -_Bool l_to_string(struct list *_list_, FILE *fptr); -_Bool l_print(struct list *_list_, FILE *fptr, const char *start, const char *separator, const char *end); - -#endif /* CMC_CMC_LIST_TEST_H */ diff --git a/tests/include/tst_cmc_queue.h b/tests/include/tst_cmc_queue.h deleted file mode 100644 index 1fcd7b1..0000000 --- a/tests/include/tst_cmc_queue.h +++ /dev/null @@ -1,71 +0,0 @@ - -#ifndef CMC_CMC_QUEUE_TEST_H -#define CMC_CMC_QUEUE_TEST_H - -#include "macro_collections.h" - -struct queue -{ - size_t *buffer; - size_t capacity; - size_t count; - size_t front; - size_t back; - int flag; - struct queue_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct queue_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct queue *q_new(size_t capacity, struct queue_fval *f_val); -struct queue *q_new_custom(size_t capacity, struct queue_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void q_clear(struct queue *_queue_); -void q_free(struct queue *_queue_); -void q_customize(struct queue *_queue_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool q_enqueue(struct queue *_queue_, size_t value); -_Bool q_dequeue(struct queue *_queue_); -size_t q_peek(struct queue *_queue_); -_Bool q_contains(struct queue *_queue_, size_t value); -_Bool q_empty(struct queue *_queue_); -_Bool q_full(struct queue *_queue_); -size_t q_count(struct queue *_queue_); -size_t q_capacity(struct queue *_queue_); -int q_flag(struct queue *_queue_); -_Bool q_resize(struct queue *_queue_, size_t capacity); -struct queue *q_copy_of(struct queue *_queue_); -_Bool q_equals(struct queue *_queue1_, struct queue *_queue2_); -struct queue_iter -{ - struct queue *target; - size_t cursor; - size_t index; - _Bool start; - _Bool end; -}; -struct queue_iter q_iter_start(struct queue *target); -struct queue_iter q_iter_end(struct queue *target); -_Bool q_iter_at_start(struct queue_iter *iter); -_Bool q_iter_at_end(struct queue_iter *iter); -_Bool q_iter_to_start(struct queue_iter *iter); -_Bool q_iter_to_end(struct queue_iter *iter); -_Bool q_iter_next(struct queue_iter *iter); -_Bool q_iter_prev(struct queue_iter *iter); -_Bool q_iter_advance(struct queue_iter *iter, size_t steps); -_Bool q_iter_rewind(struct queue_iter *iter, size_t steps); -_Bool q_iter_go_to(struct queue_iter *iter, size_t index); -size_t q_iter_value(struct queue_iter *iter); -size_t *q_iter_rvalue(struct queue_iter *iter); -size_t q_iter_index(struct queue_iter *iter); -_Bool q_to_string(struct queue *_queue_, FILE *fptr); -_Bool q_print(struct queue *_queue_, FILE *fptr, const char *start, const char *separator, const char *end); - -#endif /* CMC_CMC_QUEUE_TEST_H */ diff --git a/tests/include/tst_cmc_sortedlist.h b/tests/include/tst_cmc_sortedlist.h deleted file mode 100644 index a34b155..0000000 --- a/tests/include/tst_cmc_sortedlist.h +++ /dev/null @@ -1,72 +0,0 @@ - -#ifndef CMC_CMC_SORTEDLIST_TEST_H -#define CMC_CMC_SORTEDLIST_TEST_H - -#include "macro_collections.h" - -struct sortedlist -{ - size_t *buffer; - size_t capacity; - size_t count; - _Bool is_sorted; - int flag; - struct sortedlist_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct sortedlist_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct sortedlist *sl_new(size_t capacity, struct sortedlist_fval *f_val); -struct sortedlist *sl_new_custom(size_t capacity, struct sortedlist_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void sl_clear(struct sortedlist *_list_); -void sl_free(struct sortedlist *_list_); -void sl_customize(struct sortedlist *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool sl_insert(struct sortedlist *_list_, size_t value); -_Bool sl_remove(struct sortedlist *_list_, size_t index); -size_t sl_max(struct sortedlist *_list_); -size_t sl_min(struct sortedlist *_list_); -size_t sl_get(struct sortedlist *_list_, size_t index); -size_t sl_index_of(struct sortedlist *_list_, size_t value, _Bool from_start); -_Bool sl_contains(struct sortedlist *_list_, size_t value); -_Bool sl_empty(struct sortedlist *_list_); -_Bool sl_full(struct sortedlist *_list_); -size_t sl_count(struct sortedlist *_list_); -size_t sl_capacity(struct sortedlist *_list_); -int sl_flag(struct sortedlist *_list_); -_Bool sl_resize(struct sortedlist *_list_, size_t capacity); -void sl_sort(struct sortedlist *_list_); -struct sortedlist *sl_copy_of(struct sortedlist *_list_); -_Bool sl_equals(struct sortedlist *_list1_, struct sortedlist *_list2_); -struct sortedlist_iter -{ - struct sortedlist *target; - size_t cursor; - _Bool start; - _Bool end; -}; -struct sortedlist_iter sl_iter_start(struct sortedlist *target); -struct sortedlist_iter sl_iter_end(struct sortedlist *target); -_Bool sl_iter_at_start(struct sortedlist_iter *iter); -_Bool sl_iter_at_end(struct sortedlist_iter *iter); -_Bool sl_iter_to_start(struct sortedlist_iter *iter); -_Bool sl_iter_to_end(struct sortedlist_iter *iter); -_Bool sl_iter_next(struct sortedlist_iter *iter); -_Bool sl_iter_prev(struct sortedlist_iter *iter); -_Bool sl_iter_advance(struct sortedlist_iter *iter, size_t steps); -_Bool sl_iter_rewind(struct sortedlist_iter *iter, size_t steps); -_Bool sl_iter_go_to(struct sortedlist_iter *iter, size_t index); -size_t sl_iter_value(struct sortedlist_iter *iter); -size_t sl_iter_index(struct sortedlist_iter *iter); -_Bool sl_to_string(struct sortedlist *_list_, FILE *fptr); -_Bool sl_print(struct sortedlist *_list_, FILE *fptr, const char *start, const char *separator, const char *end); - -#endif /* CMC_CMC_SORTEDLIST_TEST_H */ diff --git a/tests/include/tst_cmc_stack.h b/tests/include/tst_cmc_stack.h deleted file mode 100644 index 6f510d0..0000000 --- a/tests/include/tst_cmc_stack.h +++ /dev/null @@ -1,68 +0,0 @@ - -#ifndef CMC_CMC_STACK_TEST_H -#define CMC_CMC_STACK_TEST_H - -#include "macro_collections.h" - -struct stack -{ - size_t *buffer; - size_t capacity; - size_t count; - int flag; - struct stack_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct stack_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct stack *s_new(size_t capacity, struct stack_fval *f_val); -struct stack *s_new_custom(size_t capacity, struct stack_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void s_clear(struct stack *_stack_); -void s_free(struct stack *_stack_); -void s_customize(struct stack *_stack_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool s_push(struct stack *_stack_, size_t value); -_Bool s_pop(struct stack *_stack_); -size_t s_top(struct stack *_stack_); -_Bool s_contains(struct stack *_stack_, size_t value); -_Bool s_empty(struct stack *_stack_); -_Bool s_full(struct stack *_stack_); -size_t s_count(struct stack *_stack_); -size_t s_capacity(struct stack *_stack_); -int s_flag(struct stack *_stack_); -_Bool s_resize(struct stack *_stack_, size_t capacity); -struct stack *s_copy_of(struct stack *_stack_); -_Bool s_equals(struct stack *_stack1_, struct stack *_stack2_); -struct stack_iter -{ - struct stack *target; - size_t cursor; - _Bool start; - _Bool end; -}; -struct stack_iter s_iter_start(struct stack *target); -struct stack_iter s_iter_end(struct stack *target); -_Bool s_iter_at_start(struct stack_iter *iter); -_Bool s_iter_at_end(struct stack_iter *iter); -_Bool s_iter_to_start(struct stack_iter *iter); -_Bool s_iter_to_end(struct stack_iter *iter); -_Bool s_iter_next(struct stack_iter *iter); -_Bool s_iter_prev(struct stack_iter *iter); -_Bool s_iter_advance(struct stack_iter *iter, size_t steps); -_Bool s_iter_rewind(struct stack_iter *iter, size_t steps); -_Bool s_iter_go_to(struct stack_iter *iter, size_t index); -size_t s_iter_value(struct stack_iter *iter); -size_t *s_iter_rvalue(struct stack_iter *iter); -size_t s_iter_index(struct stack_iter *iter); -_Bool s_to_string(struct stack *_stack_, FILE *fptr); -_Bool s_print(struct stack *_stack_, FILE *fptr, const char *start, const char *separator, const char *end); - -#endif /* CMC_CMC_STACK_TEST_H */ diff --git a/tests/include/tst_cmc_treemap.h b/tests/include/tst_cmc_treemap.h deleted file mode 100644 index 005ad91..0000000 --- a/tests/include/tst_cmc_treemap.h +++ /dev/null @@ -1,92 +0,0 @@ - -#ifndef CMC_CMC_TREEMAP_TEST_H -#define CMC_CMC_TREEMAP_TEST_H - -#include "macro_collections.h" - -struct treemap -{ - struct treemap_node *root; - size_t count; - int flag; - struct treemap_fkey *f_key; - struct treemap_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct treemap_node -{ - size_t key; - size_t value; - unsigned char height; - struct treemap_node *right; - struct treemap_node *left; - struct treemap_node *parent; -}; -struct treemap_fkey -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct treemap_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct treemap *tm_new(struct treemap_fkey *f_key, struct treemap_fval *f_val); -struct treemap *tm_new_custom(struct treemap_fkey *f_key, struct treemap_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void tm_clear(struct treemap *_map_); -void tm_free(struct treemap *_map_); -void tm_customize(struct treemap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool tm_insert(struct treemap *_map_, size_t key, size_t value); -_Bool tm_update(struct treemap *_map_, size_t key, size_t new_value, size_t *old_value); -_Bool tm_remove(struct treemap *_map_, size_t key, size_t *out_value); -_Bool tm_max(struct treemap *_map_, size_t *key, size_t *value); -_Bool tm_min(struct treemap *_map_, size_t *key, size_t *value); -size_t tm_get(struct treemap *_map_, size_t key); -size_t *tm_get_ref(struct treemap *_map_, size_t key); -_Bool tm_contains(struct treemap *_map_, size_t key); -_Bool tm_empty(struct treemap *_map_); -size_t tm_count(struct treemap *_map_); -int tm_flag(struct treemap *_map_); -struct treemap *tm_copy_of(struct treemap *_map_); -_Bool tm_equals(struct treemap *_map1_, struct treemap *_map2_); -struct treemap_iter -{ - struct treemap *target; - struct treemap_node *cursor; - struct treemap_node *first; - struct treemap_node *last; - size_t index; - _Bool start; - _Bool end; -}; -struct treemap_iter tm_iter_start(struct treemap *target); -struct treemap_iter tm_iter_end(struct treemap *target); -_Bool tm_iter_at_start(struct treemap_iter *iter); -_Bool tm_iter_at_end(struct treemap_iter *iter); -_Bool tm_iter_to_start(struct treemap_iter *iter); -_Bool tm_iter_to_end(struct treemap_iter *iter); -_Bool tm_iter_next(struct treemap_iter *iter); -_Bool tm_iter_prev(struct treemap_iter *iter); -_Bool tm_iter_advance(struct treemap_iter *iter, size_t steps); -_Bool tm_iter_rewind(struct treemap_iter *iter, size_t steps); -_Bool tm_iter_go_to(struct treemap_iter *iter, size_t index); -size_t tm_iter_key(struct treemap_iter *iter); -size_t tm_iter_value(struct treemap_iter *iter); -size_t *tm_iter_rvalue(struct treemap_iter *iter); -size_t tm_iter_index(struct treemap_iter *iter); -_Bool tm_to_string(struct treemap *_map_, FILE *fptr); -_Bool tm_print(struct treemap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, - const char *key_val_sep); - -#endif /* CMC_CMC_TREEMAP_TEST_H */ diff --git a/tests/include/tst_cmc_treeset.h b/tests/include/tst_cmc_treeset.h deleted file mode 100644 index 9bca697..0000000 --- a/tests/include/tst_cmc_treeset.h +++ /dev/null @@ -1,84 +0,0 @@ - -#ifndef CMC_CMC_TREESET_TEST_H -#define CMC_CMC_TREESET_TEST_H - -#include "macro_collections.h" - -struct treeset -{ - struct treeset_node *root; - size_t count; - int flag; - struct treeset_fval *f_val; - struct cmc_alloc_node *alloc; - struct cmc_callbacks *callbacks; -}; -struct treeset_node -{ - size_t value; - unsigned char height; - struct treeset_node *right; - struct treeset_node *left; - struct treeset_node *parent; -}; -struct treeset_fval -{ - int (*cmp)(size_t, size_t); - size_t (*cpy)(size_t); - _Bool (*str)(FILE *, size_t); - void (*free)(size_t); - size_t (*hash)(size_t); - int (*pri)(size_t, size_t); -}; -struct treeset *ts_new(struct treeset_fval *f_val); -struct treeset *ts_new_custom(struct treeset_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks); -void ts_clear(struct treeset *_set_); -void ts_free(struct treeset *_set_); -void ts_customize(struct treeset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); -_Bool ts_insert(struct treeset *_set_, size_t value); -_Bool ts_remove(struct treeset *_set_, size_t value); -_Bool ts_max(struct treeset *_set_, size_t *value); -_Bool ts_min(struct treeset *_set_, size_t *value); -_Bool ts_contains(struct treeset *_set_, size_t value); -_Bool ts_empty(struct treeset *_set_); -size_t ts_count(struct treeset *_set_); -int ts_flag(struct treeset *_set_); -struct treeset *ts_copy_of(struct treeset *_set_); -_Bool ts_equals(struct treeset *_set1_, struct treeset *_set2_); -struct treeset_iter -{ - struct treeset *target; - struct treeset_node *cursor; - struct treeset_node *first; - struct treeset_node *last; - size_t index; - _Bool start; - _Bool end; -}; -struct treeset_iter ts_iter_start(struct treeset *target); -struct treeset_iter ts_iter_end(struct treeset *target); -_Bool ts_iter_at_start(struct treeset_iter *iter); -_Bool ts_iter_at_end(struct treeset_iter *iter); -_Bool ts_iter_to_start(struct treeset_iter *iter); -_Bool ts_iter_to_end(struct treeset_iter *iter); -_Bool ts_iter_next(struct treeset_iter *iter); -_Bool ts_iter_prev(struct treeset_iter *iter); -_Bool ts_iter_advance(struct treeset_iter *iter, size_t steps); -_Bool ts_iter_rewind(struct treeset_iter *iter, size_t steps); -_Bool ts_iter_go_to(struct treeset_iter *iter, size_t index); -size_t ts_iter_value(struct treeset_iter *iter); -size_t ts_iter_index(struct treeset_iter *iter); -struct treeset *ts_union(struct treeset *_set1_, struct treeset *_set2_); -struct treeset *ts_intersection(struct treeset *_set1_, struct treeset *_set2_); -struct treeset *ts_difference(struct treeset *_set1_, struct treeset *_set2_); -struct treeset *ts_symmetric_difference(struct treeset *_set1_, struct treeset *_set2_); -_Bool ts_is_subset(struct treeset *_set1_, struct treeset *_set2_); -_Bool ts_is_superset(struct treeset *_set1_, struct treeset *_set2_); -_Bool ts_is_proper_subset(struct treeset *_set1_, struct treeset *_set2_); -_Bool ts_is_proper_superset(struct treeset *_set1_, struct treeset *_set2_); -_Bool ts_is_disjointset(struct treeset *_set1_, struct treeset *_set2_); -_Bool ts_to_string(struct treeset *_set_, FILE *fptr); -_Bool ts_print(struct treeset *_set_, FILE *fptr, const char *start, const char *separator, const char *end); - -#endif /* CMC_CMC_TREESET_TEST_H */ diff --git a/tests/main.c b/tests/main.c deleted file mode 100644 index 61d40c7..0000000 --- a/tests/main.c +++ /dev/null @@ -1,102 +0,0 @@ -#include -#include - -#include "unt_cmc_bitset.h" -#include "unt_cmc_deque.h" -#include "unt_cmc_hashbidimap.h" -#include "unt_cmc_hashmap.h" -#include "unt_cmc_hashmultimap.h" -#include "unt_cmc_hashmultiset.h" -#include "unt_cmc_hashset.h" -#include "unt_cmc_heap.h" -#include "unt_cmc_intervalheap.h" -#include "unt_cmc_linkedlist.h" -#include "unt_cmc_list.h" -#include "unt_cmc_queue.h" -#include "unt_cmc_sortedlist.h" -#include "unt_cmc_stack.h" -#include "unt_cmc_treemap.h" -#include "unt_cmc_treeset.h" - -#include "unt_utl_foreach.h" - -#include "utl_assert.h" -#include "utl_timer.h" - -#include "utl.h" - -#define cmc_run(unit, unit_fails, test_fails) \ - do \ - { \ - uintmax_t f = unit(); \ - if (f != 0) \ - unit_fails += 1; \ - test_fails += f; \ - } while (0) - -int main(void) -{ - // clang-format off - printf(" +---------------------------------------------------------------+\n"); - printf(" | C Macro Collections Library |\n"); - printf(" | |\n"); - printf(" | Test Suite |\n"); - printf(" | |\n"); - printf(" | https://github.com/LeoVen/C-Macro-Collections |\n"); - printf(" | Leonardo Vencovsky (leonardo.vencovsky@gmail.com) |\n"); - printf(" +---------------------------------------------------------------+\n\n"); - // clang-format on - - struct cmc_timer timer; - - cmc_timer_start(timer); - uintmax_t tests = 0, units = 0; - - cmc_run(CMCBitSet, units, tests); - cmc_run(CMCBitSetIter, units, tests); - cmc_run(CMCDeque, units, tests); - cmc_run(CMCDequeIter, units, tests); - cmc_run(CMCHashBidiMap, units, tests); - cmc_run(CMCHashBidiMapIter, units, tests); - cmc_run(CMCHashMap, units, tests); - cmc_run(CMCHashMapIter, units, tests); - cmc_run(CMCHashMultiMap, units, tests); - cmc_run(CMCHashMultiMapIter, units, tests); - cmc_run(CMCHashMultiSet, units, tests); - cmc_run(CMCHashMultiSetIter, units, tests); - cmc_run(CMCHashSet, units, tests); - cmc_run(CMCHashSetIter, units, tests); - cmc_run(CMCHeap, units, tests); - cmc_run(CMCHeapIter, units, tests); - cmc_run(CMCIntervalHeap, units, tests); - cmc_run(CMCIntervalHeapIter, units, tests); - cmc_run(CMCLinkedList, units, tests); - cmc_run(CMCLinkedListIter, units, tests); - cmc_run(CMCList, units, tests); - cmc_run(CMCListIter, units, tests); - cmc_run(CMCQueue, units, tests); - cmc_run(CMCQueueIter, units, tests); - cmc_run(CMCSortedList, units, tests); - cmc_run(CMCSortedListIter, units, tests); - cmc_run(CMCStack, units, tests); - cmc_run(CMCStackIter, units, tests); - cmc_run(CMCTreeMap, units, tests); - cmc_run(CMCTreeMapIter, units, tests); - cmc_run(CMCTreeSet, units, tests); - cmc_run(CMCTreeSetIter, units, tests); - - cmc_run(ForEach, units, tests); - - cmc_timer_stop(timer); - - printf(" +---------------------------------------------------------------+\n"); - printf(" | SUMMARY |\n"); - printf(" +---------------------------------------------------------------+\n"); - printf(" | Total Units Failed : %25" PRIuMAX " units |\n", units); - printf(" | Total Tests Failed : %25" PRIuMAX " tests |\n", tests); - printf(" | Total Asserts Failed : %25" PRIuMAX " asserts |\n", cmc_assert_failed); - printf(" | Total Runtime : %25.0lf milliseconds |\n", timer.result); - printf(" +---------------------------------------------------------------+\n"); - - return tests; -} diff --git a/tests/src/tst_cmc_bitset.c b/tests/src/tst_cmc_bitset.c deleted file mode 100644 index 1ae7c75..0000000 --- a/tests/src/tst_cmc_bitset.c +++ /dev/null @@ -1,294 +0,0 @@ - -#include "tst_cmc_bitset.h" - -_Bool bs_impl_resize(struct bitset *_bitset_, size_t n_bits, _Bool do_resize); -struct bitset *bs_new(size_t n_bits) -{ - return bs_new_custom(n_bits, ((void *)0), ((void *)0)); -} -struct bitset *bs_new_custom(size_t n_bits, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (n_bits < 1) - return ((void *)0); - if (!alloc) - alloc = &cmc_alloc_node_default; - size_t capacity = cmc_bidx_to_widx(n_bits - 1) + 1; - struct bitset *_bitset_ = alloc->malloc(sizeof(struct bitset)); - if (!_bitset_) - return ((void *)0); - _bitset_->buffer = alloc->calloc(capacity, sizeof(cmc_bitset_word)); - if (!_bitset_->buffer) - { - alloc->free(_bitset_); - return ((void *)0); - } - _bitset_->capacity = capacity; - _bitset_->flag = CMC_FLAG_OK; - _bitset_->alloc = alloc; - (_bitset_)->callbacks = callbacks; - return _bitset_; -} -struct bitset bs_init(size_t n_bits) -{ - return bs_init_custom(n_bits, ((void *)0), ((void *)0)); -} -struct bitset bs_init_custom(size_t n_bits, struct cmc_alloc_node *alloc, - struct cmc_callbacks *__attribute__((__unused__)) (callbacks)) -{ - ; - struct bitset _bitset_ = { 0 }; - if (n_bits < 1) - return _bitset_; - if (!alloc) - alloc = &cmc_alloc_node_default; - size_t capacity = cmc_bidx_to_widx(n_bits - 1) + 1; - _bitset_.buffer = alloc->calloc(capacity, sizeof(cmc_bitset_word)); - if (!_bitset_.buffer) - return _bitset_; - _bitset_.capacity = capacity; - _bitset_.flag = CMC_FLAG_OK; - _bitset_.alloc = alloc; - (&_bitset_)->callbacks = callbacks; - return _bitset_; -} -void bs_free(struct bitset *_bitset_) -{ - free(_bitset_->buffer); - free(_bitset_); -} -void bs_release(struct bitset _bitset_) -{ - free(_bitset_.buffer); -} -void bs_customize(struct bitset *_bitset_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (!alloc) - _bitset_->alloc = &cmc_alloc_node_default; - else - _bitset_->alloc = alloc; - (_bitset_)->callbacks = callbacks; - _bitset_->flag = CMC_FLAG_OK; -} -_Bool bs_set(struct bitset *_bitset_, size_t bit_index) -{ - if (!bs_impl_resize(_bitset_, bit_index + 1, 0)) - return 0; - const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; - size_t i = cmc_bidx_to_widx(bit_index); - _bitset_->buffer[i] |= ((cmc_bitset_word)1) << (bit_index % bits); - _bitset_->flag = CMC_FLAG_OK; - if ((_bitset_)->callbacks && (_bitset_)->callbacks->create) - (_bitset_)->callbacks->create(); - ; - return 1; -} -_Bool bs_set_range(struct bitset *_bitset_, size_t from, size_t to) -{ - if (to < from) - { - _bitset_->flag = CMC_FLAG_INVALID; - return 0; - } - if (!bs_impl_resize(_bitset_, to + 1, 0)) - return 0; - size_t start_index = cmc_bidx_to_widx(from); - size_t end_index = cmc_bidx_to_widx(to); - const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; - const cmc_bitset_word ones = ~((cmc_bitset_word)0); - cmc_bitset_word shift_start = from % bits; - cmc_bitset_word shift_end = (cmc_bitset_word)(-(to + 1)) % bits; - cmc_bitset_word start_mask = ones << shift_start; - cmc_bitset_word end_mask = ones >> shift_end; - if (start_index == end_index) - { - _bitset_->buffer[end_index] |= (start_mask & end_mask); - } - else - { - _bitset_->buffer[start_index] |= start_mask; - for (size_t i = start_index + 1; i < end_index; i++) - _bitset_->buffer[i] |= ~((cmc_bitset_word)0); - _bitset_->buffer[end_index] |= end_mask; - } - _bitset_->flag = CMC_FLAG_OK; - if ((_bitset_)->callbacks && (_bitset_)->callbacks->create) - (_bitset_)->callbacks->create(); - ; - return 1; -} -_Bool bs_clear(struct bitset *_bitset_, size_t bit_index) -{ - if (!bs_impl_resize(_bitset_, bit_index + 1, 0)) - return 0; - const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; - size_t i = cmc_bidx_to_widx(bit_index); - _bitset_->buffer[i] &= ~(((cmc_bitset_word)1) << (bit_index % bits)); - _bitset_->flag = CMC_FLAG_OK; - if ((_bitset_)->callbacks && (_bitset_)->callbacks->delete) - (_bitset_)->callbacks->delete (); - ; - return 1; -} -_Bool bs_clear_range(struct bitset *_bitset_, size_t from, size_t to) -{ - if (to < from) - { - _bitset_->flag = CMC_FLAG_INVALID; - return 0; - } - if (!bs_impl_resize(_bitset_, to + 1, 0)) - return 0; - size_t start_index = cmc_bidx_to_widx(from); - size_t end_index = cmc_bidx_to_widx(to); - const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; - const cmc_bitset_word ones = ~((cmc_bitset_word)0); - cmc_bitset_word shift_start = from % bits; - cmc_bitset_word shift_end = (cmc_bitset_word)(-(to + 1)) % bits; - cmc_bitset_word start_mask = ones << shift_start; - cmc_bitset_word end_mask = ones >> shift_end; - if (start_index == end_index) - { - _bitset_->buffer[end_index] &= ~(start_mask & end_mask); - } - else - { - _bitset_->buffer[start_index] &= ~start_mask; - for (size_t i = start_index + 1; i < end_index; i++) - _bitset_->buffer[i] = 0; - _bitset_->buffer[end_index] &= ~end_mask; - } - _bitset_->flag = CMC_FLAG_OK; - if ((_bitset_)->callbacks && (_bitset_)->callbacks->delete) - (_bitset_)->callbacks->delete (); - ; - return 1; -} -_Bool bs_flip(struct bitset *_bitset_, size_t bit_index) -{ - if (!bs_impl_resize(_bitset_, bit_index + 1, 0)) - return 0; - const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; - size_t i = cmc_bidx_to_widx(bit_index); - _bitset_->buffer[i] ^= ((cmc_bitset_word)1) << (bit_index % bits); - _bitset_->flag = CMC_FLAG_OK; - if ((_bitset_)->callbacks && (_bitset_)->callbacks->update) - (_bitset_)->callbacks->update(); - ; - return 1; -} -_Bool bs_flip_range(struct bitset *_bitset_, size_t from, size_t to) -{ - if (to < from) - { - _bitset_->flag = CMC_FLAG_INVALID; - return 0; - } - if (!bs_impl_resize(_bitset_, to + 1, 0)) - return 0; - size_t start_index = cmc_bidx_to_widx(from); - size_t end_index = cmc_bidx_to_widx(to); - const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; - const cmc_bitset_word ones = ~((cmc_bitset_word)0); - cmc_bitset_word shift_start = from % bits; - cmc_bitset_word shift_end = (cmc_bitset_word)(-(to + 1)) % bits; - cmc_bitset_word start_mask = ones << shift_start; - cmc_bitset_word end_mask = ones >> shift_end; - if (start_index == end_index) - { - _bitset_->buffer[end_index] ^= (start_mask & end_mask); - } - else - { - _bitset_->buffer[start_index] ^= start_mask; - for (size_t i = start_index + 1; i < end_index; i++) - _bitset_->buffer[i] ^= ones; - _bitset_->buffer[end_index] ^= end_mask; - } - _bitset_->flag = CMC_FLAG_OK; - if ((_bitset_)->callbacks && (_bitset_)->callbacks->update) - (_bitset_)->callbacks->update(); - ; - return 1; -} -_Bool bs_put(struct bitset *_bitset_, size_t bit_index, _Bool state) -{ - if (state) - return bs_set(_bitset_, bit_index); - else - return bs_clear(_bitset_, bit_index); -} -_Bool bs_put_range(struct bitset *_bitset_, size_t from, size_t to, _Bool state) -{ - if (state) - return bs_set_range(_bitset_, from, to); - else - return bs_clear_range(_bitset_, from, to); -} -_Bool bs_set_all(struct bitset *_bitset_) -{ - for (size_t i = 0; i < _bitset_->capacity; i++) - _bitset_->buffer[i] = ~((cmc_bitset_word)0); - _bitset_->flag = CMC_FLAG_OK; - if ((_bitset_)->callbacks && (_bitset_)->callbacks->create) - (_bitset_)->callbacks->create(); - ; - return 1; -} -_Bool bs_clear_all(struct bitset *_bitset_) -{ - for (size_t i = 0; i < _bitset_->capacity; i++) - _bitset_->buffer[i] = 0; - _bitset_->flag = CMC_FLAG_OK; - if ((_bitset_)->callbacks && (_bitset_)->callbacks->delete) - (_bitset_)->callbacks->delete (); - ; - return 1; -} -_Bool bs_flip_all(struct bitset *_bitset_) -{ - for (size_t i = 0; i < _bitset_->capacity; i++) - _bitset_->buffer[i] ^= ~((cmc_bitset_word)0); - _bitset_->flag = CMC_FLAG_OK; - if ((_bitset_)->callbacks && (_bitset_)->callbacks->create) - (_bitset_)->callbacks->create(); - ; - return 1; -} -_Bool bs_get(struct bitset *_bitset_, size_t bit_index) -{ - const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8; - cmc_bitset_word w = _bitset_->buffer[cmc_bidx_to_widx(bit_index)]; - return w & ((cmc_bitset_word)1 << (bit_index % bits)); -} -_Bool bs_resize(struct bitset *_bitset_, size_t n_bits) -{ - return bs_impl_resize(_bitset_, n_bits, 1); -} -_Bool bs_impl_resize(struct bitset *_bitset_, size_t n_bits, _Bool do_resize) -{ - if (n_bits == 0) - { - _bitset_->flag = CMC_FLAG_INVALID; - return 0; - } - size_t words = cmc_bidx_to_widx(n_bits - 1) + 1; - if (!do_resize && words <= _bitset_->capacity) - return 1; - cmc_bitset_word *new_buffer = realloc(_bitset_->buffer, words * sizeof(cmc_bitset_word)); - if (!new_buffer) - { - _bitset_->flag = CMC_FLAG_ALLOC; - return 0; - } - _bitset_->buffer = new_buffer; - if (_bitset_->capacity < words) - memset(_bitset_->buffer + _bitset_->capacity, 0, (words - _bitset_->capacity) * sizeof(cmc_bitset_word)); - _bitset_->capacity = words; - if ((_bitset_)->callbacks && (_bitset_)->callbacks->resize) - (_bitset_)->callbacks->resize(); - ; - _bitset_->flag = CMC_FLAG_OK; - return 1; -} diff --git a/tests/src/tst_cmc_deque.c b/tests/src/tst_cmc_deque.c deleted file mode 100644 index a815278..0000000 --- a/tests/src/tst_cmc_deque.c +++ /dev/null @@ -1,516 +0,0 @@ - -#include "tst_cmc_deque.h" - -struct deque *d_new(size_t capacity, struct deque_fval *f_val) -{ - return d_new_custom(capacity, f_val, ((void *)0), ((void *)0)); -} -struct deque *d_new_custom(size_t capacity, struct deque_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) -{ - ; - if (capacity < 1) - return ((void *)0); - if (!f_val) - return ((void *)0); - if (!alloc) - alloc = &cmc_alloc_node_default; - struct deque *_deque_ = alloc->malloc(sizeof(struct deque)); - if (!_deque_) - return ((void *)0); - _deque_->buffer = alloc->calloc(capacity, sizeof(size_t)); - if (!_deque_->buffer) - { - alloc->free(_deque_); - return ((void *)0); - } - _deque_->capacity = capacity; - _deque_->count = 0; - _deque_->front = 0; - _deque_->back = 0; - _deque_->flag = CMC_FLAG_OK; - _deque_->f_val = f_val; - _deque_->alloc = alloc; - (_deque_)->callbacks = callbacks; - return _deque_; -} -void d_clear(struct deque *_deque_) -{ - if (_deque_->f_val->free) - { - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) - { - _deque_->f_val->free(_deque_->buffer[i]); - i = (i + 1) % _deque_->capacity; - } - } - memset(_deque_->buffer, 0, sizeof(size_t) * _deque_->capacity); - _deque_->count = 0; - _deque_->front = 0; - _deque_->back = 0; - _deque_->flag = CMC_FLAG_OK; -} -void d_free(struct deque *_deque_) -{ - if (_deque_->f_val->free) - { - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) - { - _deque_->f_val->free(_deque_->buffer[i]); - i = (i + 1) % _deque_->capacity; - } - } - _deque_->alloc->free(_deque_->buffer); - _deque_->alloc->free(_deque_); -} -void d_customize(struct deque *_deque_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (!alloc) - _deque_->alloc = &cmc_alloc_node_default; - else - _deque_->alloc = alloc; - (_deque_)->callbacks = callbacks; - _deque_->flag = CMC_FLAG_OK; -} -_Bool d_push_front(struct deque *_deque_, size_t value) -{ - if (d_full(_deque_)) - { - if (!d_resize(_deque_, _deque_->capacity * 2)) - return 0; - } - _deque_->front = (_deque_->front == 0) ? _deque_->capacity - 1 : _deque_->front - 1; - _deque_->buffer[_deque_->front] = value; - _deque_->count++; - _deque_->flag = CMC_FLAG_OK; - if ((_deque_)->callbacks && (_deque_)->callbacks->create) - (_deque_)->callbacks->create(); - ; - return 1; -} -_Bool d_push_back(struct deque *_deque_, size_t value) -{ - if (d_full(_deque_)) - { - if (!d_resize(_deque_, _deque_->capacity * 2)) - return 0; - } - _deque_->buffer[_deque_->back] = value; - _deque_->back = (_deque_->back == _deque_->capacity - 1) ? 0 : _deque_->back + 1; - _deque_->count++; - _deque_->flag = CMC_FLAG_OK; - if ((_deque_)->callbacks && (_deque_)->callbacks->create) - (_deque_)->callbacks->create(); - ; - return 1; -} -_Bool d_pop_front(struct deque *_deque_) -{ - if (d_empty(_deque_)) - { - _deque_->flag = CMC_FLAG_EMPTY; - return 0; - } - _deque_->buffer[_deque_->front] = (size_t){ 0 }; - _deque_->front = (_deque_->front == _deque_->capacity - 1) ? 0 : _deque_->front + 1; - _deque_->count--; - _deque_->flag = CMC_FLAG_OK; - if ((_deque_)->callbacks && (_deque_)->callbacks->delete) - (_deque_)->callbacks->delete (); - ; - return 1; -} -_Bool d_pop_back(struct deque *_deque_) -{ - if (d_empty(_deque_)) - { - _deque_->flag = CMC_FLAG_EMPTY; - return 0; - } - _deque_->back = (_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1; - _deque_->buffer[_deque_->back] = (size_t){ 0 }; - _deque_->count--; - _deque_->flag = CMC_FLAG_OK; - if ((_deque_)->callbacks && (_deque_)->callbacks->delete) - (_deque_)->callbacks->delete (); - ; - return 1; -} -size_t d_front(struct deque *_deque_) -{ - if (d_empty(_deque_)) - { - _deque_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - _deque_->flag = CMC_FLAG_OK; - if ((_deque_)->callbacks && (_deque_)->callbacks->read) - (_deque_)->callbacks->read(); - ; - return _deque_->buffer[_deque_->front]; -} -size_t d_back(struct deque *_deque_) -{ - if (d_empty(_deque_)) - { - _deque_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - _deque_->flag = CMC_FLAG_OK; - if ((_deque_)->callbacks && (_deque_)->callbacks->read) - (_deque_)->callbacks->read(); - ; - return _deque_->buffer[(_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1]; -} -_Bool d_contains(struct deque *_deque_, size_t value) -{ - _deque_->flag = CMC_FLAG_OK; - _Bool result = 0; - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) - { - if (_deque_->f_val->cmp(_deque_->buffer[i], value) == 0) - { - result = 1; - break; - } - i = (i + 1) % _deque_->capacity; - } - if ((_deque_)->callbacks && (_deque_)->callbacks->read) - (_deque_)->callbacks->read(); - ; - return result; -} -_Bool d_empty(struct deque *_deque_) -{ - return _deque_->count == 0; -} -_Bool d_full(struct deque *_deque_) -{ - return _deque_->count >= _deque_->capacity; -} -size_t d_count(struct deque *_deque_) -{ - return _deque_->count; -} -size_t d_capacity(struct deque *_deque_) -{ - return _deque_->capacity; -} -int d_flag(struct deque *_deque_) -{ - return _deque_->flag; -} -_Bool d_resize(struct deque *_deque_, size_t capacity) -{ - _deque_->flag = CMC_FLAG_OK; - if (_deque_->capacity == capacity) - goto success; - if (capacity < _deque_->count) - { - _deque_->flag = CMC_FLAG_INVALID; - return 0; - } - size_t *new_buffer = _deque_->alloc->malloc(sizeof(size_t) * capacity); - if (!new_buffer) - { - _deque_->flag = CMC_FLAG_ALLOC; - return 0; - } - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) - { - new_buffer[j] = _deque_->buffer[i]; - i = (i + 1) % _deque_->capacity; - } - _deque_->alloc->free(_deque_->buffer); - _deque_->buffer = new_buffer; - _deque_->capacity = capacity; - _deque_->front = 0; - _deque_->back = _deque_->count; -success: - if ((_deque_)->callbacks && (_deque_)->callbacks->resize) - (_deque_)->callbacks->resize(); - ; - return 1; -} -struct deque *d_copy_of(struct deque *_deque_) -{ - struct deque *result = d_new_custom(_deque_->capacity, _deque_->f_val, _deque_->alloc, ((void *)0)); - if (!result) - { - _deque_->flag = CMC_FLAG_ERROR; - return ((void *)0); - } - (result)->callbacks = _deque_->callbacks; - if (_deque_->f_val->cpy) - { - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) - { - result->buffer[j] = _deque_->f_val->cpy(_deque_->buffer[i]); - i = (i + 1) % _deque_->capacity; - } - } - else - { - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) - { - result->buffer[j] = _deque_->buffer[i]; - i = (i + 1) % _deque_->capacity; - } - } - result->count = _deque_->count; - result->front = 0; - result->back = _deque_->count; - _deque_->flag = CMC_FLAG_OK; - return result; -} -_Bool d_equals(struct deque *_deque1_, struct deque *_deque2_) -{ - _deque1_->flag = CMC_FLAG_OK; - _deque2_->flag = CMC_FLAG_OK; - if (_deque1_->count != _deque2_->count) - return 0; - size_t i, j, k; - for (i = _deque1_->front, j = _deque2_->front, k = 0; k < _deque1_->count; k++) - { - if (_deque1_->f_val->cmp(_deque1_->buffer[i], _deque2_->buffer[j]) != 0) - return 0; - i = (i + 1) % _deque1_->capacity; - j = (j + 1) % _deque2_->capacity; - } - return 1; -} -struct deque d_init(size_t capacity, struct deque_fval *f_val) -{ - return d_init_custom(capacity, f_val, ((void *)0), ((void *)0)); -} -struct deque d_init_custom(size_t capacity, struct deque_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) -{ - ; - struct deque _deque_ = { 0 }; - if (capacity < 1) - return _deque_; - if (!f_val) - return _deque_; - if (!alloc) - alloc = &cmc_alloc_node_default; - _deque_.buffer = alloc->calloc(capacity, sizeof(size_t)); - if (!_deque_.buffer) - return _deque_; - _deque_.capacity = capacity; - _deque_.count = 0; - _deque_.front = 0; - _deque_.back = 0; - _deque_.flag = CMC_FLAG_OK; - _deque_.f_val = f_val; - _deque_.alloc = alloc; - (&_deque_)->callbacks = callbacks; - return _deque_; -} -void d_release(struct deque _deque_) -{ - if (_deque_.f_val->free) - { - for (size_t i = _deque_.front, j = 0; j < _deque_.count; j++) - { - _deque_.f_val->free(_deque_.buffer[i]); - i = (i + 1) % _deque_.capacity; - } - } - _deque_.alloc->free(_deque_.buffer); -} -struct deque_iter d_iter_start(struct deque *target) -{ - struct deque_iter iter; - iter.target = target; - iter.cursor = target->front; - iter.index = 0; - iter.start = 1; - iter.end = d_empty(target); - return iter; -} -struct deque_iter d_iter_end(struct deque *target) -{ - struct deque_iter iter; - iter.target = target; - if (!d_empty(target)) - { - if (iter.target->back == 0) - iter.cursor = iter.target->capacity - 1; - else - iter.cursor = iter.target->back - 1; - iter.index = iter.target->count - 1; - } - else - { - iter.cursor = 0; - iter.index = 0; - } - iter.start = d_empty(target); - iter.end = 1; - return iter; -} -_Bool d_iter_at_start(struct deque_iter *iter) -{ - return d_empty(iter->target) || iter->start; -} -_Bool d_iter_at_end(struct deque_iter *iter) -{ - return d_empty(iter->target) || iter->end; -} -_Bool d_iter_to_start(struct deque_iter *iter) -{ - if (!d_empty(iter->target)) - { - iter->cursor = iter->target->front; - iter->index = 0; - iter->start = 1; - iter->end = 0; - return 1; - } - return 0; -} -_Bool d_iter_to_end(struct deque_iter *iter) -{ - if (!d_empty(iter->target)) - { - if (iter->target->back == 0) - iter->cursor = iter->target->capacity - 1; - else - iter->cursor = iter->target->back - 1; - iter->index = iter->target->count - 1; - iter->start = 0; - iter->end = 1; - return 1; - } - return 0; -} -_Bool d_iter_next(struct deque_iter *iter) -{ - if (iter->end) - return 0; - if (iter->index + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - iter->start = d_empty(iter->target); - iter->cursor = (iter->cursor + 1) % (iter->target->capacity); - iter->index++; - return 1; -} -_Bool d_iter_prev(struct deque_iter *iter) -{ - if (iter->start) - return 0; - if (iter->index == 0) - { - iter->start = 1; - return 0; - } - iter->end = d_empty(iter->target); - iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1; - iter->index--; - return 1; -} -_Bool d_iter_advance(struct deque_iter *iter, size_t steps) -{ - if (iter->end) - return 0; - if (iter->index + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - if (steps == 0 || iter->index + steps >= iter->target->count) - return 0; - iter->start = d_empty(iter->target); - iter->index += steps; - iter->cursor = (iter->cursor + steps) % iter->target->capacity; - return 1; -} -_Bool d_iter_rewind(struct deque_iter *iter, size_t steps) -{ - if (iter->start) - return 0; - if (iter->index == 0) - { - iter->start = 1; - return 0; - } - if (steps == 0 || iter->index < steps) - return 0; - iter->end = d_empty(iter->target); - iter->index -= steps; - if (iter->cursor < steps) - iter->cursor += iter->target->capacity; - iter->cursor -= steps; - return 1; -} -_Bool d_iter_go_to(struct deque_iter *iter, size_t index) -{ - if (index >= iter->target->count) - return 0; - if (iter->index > index) - return d_iter_rewind(iter, iter->index - index); - else if (iter->index < index) - return d_iter_advance(iter, index - iter->index); - return 1; -} -size_t d_iter_value(struct deque_iter *iter) -{ - if (d_empty(iter->target)) - return (size_t){ 0 }; - return iter->target->buffer[iter->cursor]; -} -size_t *d_iter_rvalue(struct deque_iter *iter) -{ - if (d_empty(iter->target)) - return ((void *)0); - return &(iter->target->buffer[iter->cursor]); -} -size_t d_iter_index(struct deque_iter *iter) -{ - return iter->index; -} -_Bool d_to_string(struct deque *_deque_, FILE *fptr) -{ - struct deque *d_ = _deque_; - return 0 <= fprintf(fptr, - "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" - "I64u" - ", " - "count:%" - "I64u" - ", " - "front:%" - "I64u" - ", " - "back:%" - "I64u" - ", " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }", - "deque", "size_t", d_, d_->buffer, d_->capacity, d_->count, d_->front, d_->back, d_->flag, - d_->f_val, d_->alloc, (d_)->callbacks); -} -_Bool d_print(struct deque *_deque_, FILE *fptr, const char *start, const char *separator, const char *end) -{ - fprintf(fptr, "%s", start); - for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) - { - if (!_deque_->f_val->str(fptr, _deque_->buffer[i])) - return 0; - i = (i + 1) % _deque_->capacity; - if (j + 1 < _deque_->count) - fprintf(fptr, "%s", separator); - } - fprintf(fptr, "%s", end); - return 1; -} diff --git a/tests/src/tst_cmc_hashbidimap.c b/tests/src/tst_cmc_hashbidimap.c deleted file mode 100644 index b7381c4..0000000 --- a/tests/src/tst_cmc_hashbidimap.c +++ /dev/null @@ -1,856 +0,0 @@ - -#include "tst_cmc_hashbidimap.h" - -static struct hashbidimap_entry *hbm_impl_new_entry(struct hashbidimap *_map_, size_t key, size_t value); -static struct hashbidimap_entry **hbm_impl_get_entry_by_key(struct hashbidimap *_map_, size_t key); -static struct hashbidimap_entry **hbm_impl_get_entry_by_val(struct hashbidimap *_map_, size_t val); -static struct hashbidimap_entry **hbm_impl_add_entry_to_key(struct hashbidimap *_map_, struct hashbidimap_entry *entry); -static struct hashbidimap_entry **hbm_impl_add_entry_to_val(struct hashbidimap *_map_, struct hashbidimap_entry *entry); -static size_t hbm_impl_calculate_size(size_t required); -static struct hashbidimap_iter hbm_impl_it_start(struct hashbidimap *_map_); -static struct hashbidimap_iter hbm_impl_it_end(struct hashbidimap *_map_); -struct hashbidimap *hbm_new(size_t capacity, double load, struct hashbidimap_fkey *f_key, - struct hashbidimap_fval *f_val) -{ - return hbm_new_custom(capacity, load, f_key, f_val, ((void *)0), ((void *)0)); -} -struct hashbidimap *hbm_new_custom(size_t capacity, double load, struct hashbidimap_fkey *f_key, - struct hashbidimap_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) -{ - ; - if (capacity == 0 || load <= 0 || load >= 1) - return ((void *)0); - if (capacity >= 0xffffffffffffffffULL * load) - return ((void *)0); - if (!f_key || !f_val) - return ((void *)0); - size_t real_capacity = hbm_impl_calculate_size(capacity / load); - if (!alloc) - alloc = &cmc_alloc_node_default; - struct hashbidimap *_map_ = alloc->malloc(sizeof(struct hashbidimap)); - if (!_map_) - return ((void *)0); - _map_->buffer = alloc->calloc(real_capacity, sizeof(struct hashbidimap_entry *[2])); - if (!_map_->buffer) - { - alloc->free(_map_->buffer); - alloc->free(_map_); - return ((void *)0); - } - _map_->count = 0; - _map_->capacity = real_capacity; - _map_->load = load; - _map_->flag = CMC_FLAG_OK; - _map_->f_key = f_key; - _map_->f_val = f_val; - _map_->flag = CMC_FLAG_OK; - _map_->alloc = alloc; - (_map_)->callbacks = callbacks; - _map_->it_start = hbm_impl_it_start; - _map_->it_end = hbm_impl_it_end; - return _map_; -} -void hbm_clear(struct hashbidimap *_map_) -{ - for (size_t i = 0; i < _map_->capacity; i++) - { - struct hashbidimap_entry *entry = _map_->buffer[i][0]; - if (entry && entry != ((void *)1)) - { - if (_map_->f_key->free) - _map_->f_key->free(entry->key); - if (_map_->f_val->free) - _map_->f_val->free(entry->value); - _map_->alloc->free(entry); - } - _map_->buffer[i][0] = ((void *)0); - _map_->buffer[i][1] = ((void *)0); - } - _map_->count = 0; - _map_->flag = CMC_FLAG_OK; -} -void hbm_free(struct hashbidimap *_map_) -{ - hbm_clear(_map_); - _map_->alloc->free(_map_->buffer); - _map_->alloc->free(_map_); -} -void hbm_customize(struct hashbidimap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (!alloc) - _map_->alloc = &cmc_alloc_node_default; - else - _map_->alloc = alloc; - (_map_)->callbacks = callbacks; - _map_->flag = CMC_FLAG_OK; -} -_Bool hbm_insert(struct hashbidimap *_map_, size_t key, size_t value) -{ - if (hbm_full(_map_)) - { - if (!hbm_resize(_map_, _map_->capacity + 1)) - return 0; - } - if (hbm_impl_get_entry_by_key(_map_, key) != ((void *)0) || hbm_impl_get_entry_by_val(_map_, value) != ((void *)0)) - { - _map_->flag = CMC_FLAG_DUPLICATE; - return 0; - } - struct hashbidimap_entry *entry = hbm_impl_new_entry(_map_, key, value); - struct hashbidimap_entry **key_entry = hbm_impl_add_entry_to_key(_map_, entry); - struct hashbidimap_entry **val_entry = hbm_impl_add_entry_to_val(_map_, entry); - if (!key_entry || !val_entry) - { - if (key_entry) - *key_entry = ((void *)1); - if (val_entry) - *val_entry = ((void *)1); - _map_->alloc->free(entry); - _map_->flag = CMC_FLAG_ERROR; - return 0; - } - _map_->count++; - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->create) - (_map_)->callbacks->create(); - ; - return 1; -} -_Bool hbm_update_key(struct hashbidimap *_map_, size_t val, size_t new_key) -{ - if (hbm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct hashbidimap_entry **key_entry, **val_entry; - val_entry = hbm_impl_get_entry_by_val(_map_, val); - if (!val_entry) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - if (_map_->f_key->cmp(new_key, (*val_entry)->key) == 0) - goto success; - if (hbm_impl_get_entry_by_key(_map_, new_key) != ((void *)0)) - { - _map_->flag = CMC_FLAG_DUPLICATE; - return 0; - } - key_entry = (*val_entry)->ref[0]; - if (!key_entry || *key_entry != *val_entry) - { - _map_->flag = CMC_FLAG_ERROR; - return 0; - } - struct hashbidimap_entry *to_add = *key_entry; - size_t tmp_key = to_add->key; - to_add->key = new_key; - *key_entry = ((void *)1); - if (!hbm_impl_add_entry_to_key(_map_, to_add)) - { - to_add->key = tmp_key; - *key_entry = to_add; - _map_->flag = CMC_FLAG_ERROR; - return 0; - } -success: - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->update) - (_map_)->callbacks->update(); - ; - return 1; -} -_Bool hbm_update_val(struct hashbidimap *_map_, size_t key, size_t new_val) -{ - if (hbm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct hashbidimap_entry **key_entry, **val_entry; - key_entry = hbm_impl_get_entry_by_key(_map_, key); - if (!key_entry) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - if (_map_->f_val->cmp(new_val, (*key_entry)->value) == 0) - goto success; - if (hbm_impl_get_entry_by_val(_map_, new_val) != ((void *)0)) - { - _map_->flag = CMC_FLAG_DUPLICATE; - return 0; - } - val_entry = (*key_entry)->ref[1]; - if (!val_entry || *val_entry != *key_entry) - { - _map_->flag = CMC_FLAG_ERROR; - return 0; - } - struct hashbidimap_entry *to_add = *val_entry; - size_t tmp_val = to_add->value; - to_add->value = new_val; - *val_entry = ((void *)1); - if (!hbm_impl_add_entry_to_val(_map_, to_add)) - { - to_add->value = tmp_val; - *val_entry = to_add; - _map_->flag = CMC_FLAG_ERROR; - return 0; - } -success: - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->update) - (_map_)->callbacks->update(); - ; - return 1; -} -_Bool hbm_remove_by_key(struct hashbidimap *_map_, size_t key, size_t *out_key, size_t *out_val) -{ - if (hbm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct hashbidimap_entry **key_entry, **val_entry; - key_entry = hbm_impl_get_entry_by_key(_map_, key); - if (!key_entry) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - val_entry = (*key_entry)->ref[1]; - if (!val_entry || *val_entry != *key_entry) - { - _map_->flag = CMC_FLAG_ERROR; - return 0; - } - if (out_key) - *out_key = (*key_entry)->key; - if (out_val) - *out_val = (*key_entry)->value; - _map_->alloc->free(*key_entry); - *key_entry = ((void *)1); - *val_entry = ((void *)1); - _map_->count--; - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->delete) - (_map_)->callbacks->delete (); - ; - return 1; -} -_Bool hbm_remove_by_val(struct hashbidimap *_map_, size_t val, size_t *out_key, size_t *out_val) -{ - if (hbm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct hashbidimap_entry **key_entry, **val_entry; - val_entry = hbm_impl_get_entry_by_val(_map_, val); - if (!val_entry) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - key_entry = (*val_entry)->ref[0]; - if (!key_entry || *key_entry != *val_entry) - { - _map_->flag = CMC_FLAG_ERROR; - return 0; - } - if (out_key) - *out_key = (*val_entry)->key; - if (out_val) - *out_val = (*val_entry)->value; - _map_->alloc->free(*val_entry); - *key_entry = ((void *)1); - *val_entry = ((void *)1); - _map_->count--; - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->delete) - (_map_)->callbacks->delete (); - ; - return 1; -} -size_t hbm_get_key(struct hashbidimap *_map_, size_t val) -{ - struct hashbidimap_entry **entry = hbm_impl_get_entry_by_val(_map_, val); - if (!entry) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return (size_t){ 0 }; - } - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->read) - (_map_)->callbacks->read(); - ; - return (*entry)->key; -} -size_t hbm_get_val(struct hashbidimap *_map_, size_t key) -{ - struct hashbidimap_entry **entry = hbm_impl_get_entry_by_key(_map_, key); - if (!entry) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return (size_t){ 0 }; - } - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->read) - (_map_)->callbacks->read(); - ; - return (*entry)->value; -} -_Bool hbm_contains_key(struct hashbidimap *_map_, size_t key) -{ - _map_->flag = CMC_FLAG_OK; - _Bool result = hbm_impl_get_entry_by_key(_map_, key) != ((void *)0); - if ((_map_)->callbacks && (_map_)->callbacks->read) - (_map_)->callbacks->read(); - ; - return result; -} -_Bool hbm_contains_val(struct hashbidimap *_map_, size_t val) -{ - _map_->flag = CMC_FLAG_OK; - _Bool result = hbm_impl_get_entry_by_val(_map_, val) != ((void *)0); - if ((_map_)->callbacks && (_map_)->callbacks->read) - (_map_)->callbacks->read(); - ; - return result; -} -_Bool hbm_empty(struct hashbidimap *_map_) -{ - return _map_->count == 0; -} -_Bool hbm_full(struct hashbidimap *_map_) -{ - return (double)_map_->capacity * _map_->load <= (double)_map_->count; -} -size_t hbm_count(struct hashbidimap *_map_) -{ - return _map_->count; -} -size_t hbm_capacity(struct hashbidimap *_map_) -{ - return _map_->capacity; -} -double hbm_load(struct hashbidimap *_map_) -{ - return _map_->load; -} -int hbm_flag(struct hashbidimap *_map_) -{ - return _map_->flag; -} -_Bool hbm_resize(struct hashbidimap *_map_, size_t capacity) -{ - _map_->flag = CMC_FLAG_OK; - if (_map_->capacity == capacity) - goto success; - if (_map_->capacity > capacity / _map_->load) - goto success; - if (capacity >= 0xffffffffffffffffULL * _map_->load) - { - _map_->flag = CMC_FLAG_ERROR; - return 0; - } - size_t new_cap = hbm_impl_calculate_size(capacity); - if (new_cap < _map_->count / _map_->load) - { - _map_->flag = CMC_FLAG_INVALID; - return 0; - } - struct hashbidimap *_new_map_ = - hbm_new_custom(capacity, _map_->load, _map_->f_key, _map_->f_val, _map_->alloc, ((void *)0)); - if (!_new_map_) - { - _map_->flag = CMC_FLAG_ALLOC; - return 0; - } - for (size_t i = 0; i < _map_->capacity; i++) - { - struct hashbidimap_entry *scan = _map_->buffer[i][0]; - if (scan && scan != ((void *)1)) - { - struct hashbidimap_entry **e1 = hbm_impl_add_entry_to_key(_new_map_, scan); - struct hashbidimap_entry **e2 = hbm_impl_add_entry_to_val(_new_map_, scan); - if (!e1 || !e2) - { - _new_map_->f_key = &(struct hashbidimap_fkey){ ((void *)0) }; - _new_map_->f_val = &(struct hashbidimap_fval){ ((void *)0) }; - _map_->alloc->free(_new_map_->buffer); - _map_->alloc->free(_new_map_); - _map_->flag = CMC_FLAG_ERROR; - return 0; - } - _new_map_->count++; - } - } - if (_map_->count != _new_map_->count) - { - _new_map_->f_key = &(struct hashbidimap_fkey){ ((void *)0) }; - _new_map_->f_val = &(struct hashbidimap_fval){ ((void *)0) }; - _map_->alloc->free(_new_map_->buffer); - _map_->alloc->free(_new_map_); - _map_->flag = CMC_FLAG_ERROR; - return 0; - } - struct hashbidimap_entry *(*tmp_buff)[2] = _map_->buffer; - _map_->buffer = _new_map_->buffer; - _map_->capacity = _new_map_->capacity; - _map_->alloc->free(tmp_buff); - _map_->alloc->free(_new_map_); -success: - if ((_map_)->callbacks && (_map_)->callbacks->resize) - (_map_)->callbacks->resize(); - ; - return 1; -} -struct hashbidimap *hbm_copy_of(struct hashbidimap *_map_) -{ - struct hashbidimap *result = hbm_new_custom(_map_->capacity * _map_->load, _map_->load, _map_->f_key, _map_->f_val, - _map_->alloc, ((void *)0)); - if (!result) - { - _map_->flag = CMC_FLAG_ERROR; - return ((void *)0); - } - (result)->callbacks = _map_->callbacks; - for (size_t i = 0; i < _map_->capacity; i++) - { - struct hashbidimap_entry *scan = _map_->buffer[i][0]; - if (scan && scan != ((void *)1)) - { - size_t tmp_key; - size_t tmp_val; - if (_map_->f_key->cpy) - tmp_key = _map_->f_key->cpy(scan->key); - else - tmp_key = scan->key; - if (_map_->f_val->cpy) - tmp_val = _map_->f_val->cpy(scan->value); - else - tmp_val = scan->value; - struct hashbidimap_entry *entry = hbm_impl_new_entry(result, tmp_key, tmp_val); - hbm_impl_add_entry_to_key(result, entry); - hbm_impl_add_entry_to_val(result, entry); - result->count++; - } - } - _map_->flag = CMC_FLAG_OK; - return result; -} -_Bool hbm_equals(struct hashbidimap *_map1_, struct hashbidimap *_map2_) -{ - _map1_->flag = CMC_FLAG_OK; - _map2_->flag = CMC_FLAG_OK; - if (_map1_->count != _map2_->count) - return 0; - struct hashbidimap *_mapA_; - struct hashbidimap *_mapB_; - if (_map1_->capacity < _map2_->capacity) - { - _mapA_ = _map1_; - _mapB_ = _map2_; - } - else - { - _mapA_ = _map2_; - _mapB_ = _map1_; - } - for (size_t i = 0; i < _mapA_->capacity; i++) - { - struct hashbidimap_entry *scan = _mapA_->buffer[i][0]; - if (scan && scan != ((void *)1)) - { - struct hashbidimap_entry **entry_B = hbm_impl_get_entry_by_key(_mapB_, scan->key); - if (!entry_B) - return 0; - if (_mapA_->f_val->cmp((*entry_B)->value, scan->value) != 0) - return 0; - } - } - return 1; -} -struct hashbidimap_iter *hbm_iter_new(struct hashbidimap *target) -{ - struct hashbidimap_iter *iter = target->alloc->malloc(sizeof(struct hashbidimap_iter)); - if (!iter) - return ((void *)0); - hbm_iter_init(iter, target); - return iter; -} -void hbm_iter_free(struct hashbidimap_iter *iter) -{ - iter->target->alloc->free(iter); -} -void hbm_iter_init(struct hashbidimap_iter *iter, struct hashbidimap *target) -{ - memset(iter, 0, sizeof(struct hashbidimap_iter)); - iter->target = target; - iter->start = 1; - iter->end = hbm_empty(target); - if (!hbm_empty(target)) - { - for (size_t i = 0; i < target->capacity; i++) - { - struct hashbidimap_entry *entry = target->buffer[i][0]; - if (entry && entry != ((void *)1)) - { - iter->first = i; - break; - } - } - iter->cursor = iter->first; - for (size_t i = target->capacity; i > 0; i--) - { - struct hashbidimap_entry *entry = target->buffer[i - 1][0]; - if (entry && entry != ((void *)1)) - { - iter->last = i - 1; - break; - } - } - } -} -_Bool hbm_iter_start(struct hashbidimap_iter *iter) -{ - return hbm_empty(iter->target) || iter->start; -} -_Bool hbm_iter_end(struct hashbidimap_iter *iter) -{ - return hbm_empty(iter->target) || iter->end; -} -void hbm_iter_to_start(struct hashbidimap_iter *iter) -{ - if (!hbm_empty(iter->target)) - { - iter->cursor = iter->first; - iter->index = 0; - iter->start = 1; - iter->end = 0; - } -} -void hbm_iter_to_end(struct hashbidimap_iter *iter) -{ - if (!hbm_empty(iter->target)) - { - iter->cursor = iter->last; - iter->index = iter->target->count - 1; - iter->start = 0; - iter->end = 1; - } -} -_Bool hbm_iter_next(struct hashbidimap_iter *iter) -{ - if (iter->end) - return 0; - if (iter->index + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - iter->start = hbm_empty(iter->target); - struct hashbidimap_entry *scan = iter->target->buffer[iter->cursor][0]; - iter->index++; - while (1) - { - iter->cursor++; - scan = iter->target->buffer[iter->cursor][0]; - if (scan != ((void *)0) && scan != ((void *)1)) - break; - } - return 1; -} -_Bool hbm_iter_prev(struct hashbidimap_iter *iter) -{ - if (iter->start) - return 0; - if (iter->index == 0) - { - iter->start = 1; - return 0; - } - iter->end = hbm_empty(iter->target); - struct hashbidimap_entry *scan = iter->target->buffer[iter->cursor][0]; - iter->index--; - while (1) - { - iter->cursor--; - scan = iter->target->buffer[iter->cursor][0]; - if (scan != ((void *)0) && scan != ((void *)1)) - break; - } - return 1; -} -_Bool hbm_iter_advance(struct hashbidimap_iter *iter, size_t steps) -{ - if (iter->end) - return 0; - if (iter->index + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - if (steps == 0 || iter->index + steps >= iter->target->count) - return 0; - for (size_t i = 0; i < steps; i++) - hbm_iter_next(iter); - return 1; -} -_Bool hbm_iter_rewind(struct hashbidimap_iter *iter, size_t steps) -{ - if (iter->start) - return 0; - if (iter->index == 0) - { - iter->start = 1; - return 0; - } - if (steps == 0 || iter->index < steps) - return 0; - for (size_t i = 0; i < steps; i++) - hbm_iter_prev(iter); - return 1; -} -_Bool hbm_iter_go_to(struct hashbidimap_iter *iter, size_t index) -{ - if (index >= iter->target->count) - return 0; - if (iter->index > index) - return hbm_iter_rewind(iter, iter->index - index); - else if (iter->index < index) - return hbm_iter_advance(iter, index - iter->index); - return 1; -} -size_t hbm_iter_key(struct hashbidimap_iter *iter) -{ - if (hbm_empty(iter->target)) - { - iter->target->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - return iter->target->buffer[iter->cursor][0]->key; -} -size_t hbm_iter_value(struct hashbidimap_iter *iter) -{ - if (hbm_empty(iter->target)) - { - iter->target->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - return iter->target->buffer[iter->cursor][0]->value; -} -size_t hbm_iter_index(struct hashbidimap_iter *iter) -{ - return iter->index; -} -static struct hashbidimap_entry *hbm_impl_new_entry(struct hashbidimap *_map_, size_t key, size_t value) -{ - struct hashbidimap_entry *entry = _map_->alloc->malloc(sizeof(struct hashbidimap_entry)); - if (!entry) - return ((void *)0); - entry->key = key; - entry->value = value; - entry->dist[0] = 0; - entry->dist[1] = 0; - entry->ref[0] = ((void *)0); - entry->ref[1] = ((void *)0); - return entry; -} -static struct hashbidimap_entry **hbm_impl_get_entry_by_key(struct hashbidimap *_map_, size_t key) -{ - size_t hash = _map_->f_key->hash(key); - size_t pos = hash % _map_->capacity; - struct hashbidimap_entry *target = _map_->buffer[pos][0]; - while (target != ((void *)0)) - { - if (target != ((void *)1) && _map_->f_key->cmp(target->key, key) == 0) - return &(_map_->buffer[pos % _map_->capacity][0]); - pos++; - target = _map_->buffer[pos % _map_->capacity][0]; - } - return ((void *)0); -} -static struct hashbidimap_entry **hbm_impl_get_entry_by_val(struct hashbidimap *_map_, size_t val) -{ - size_t hash = _map_->f_val->hash(val); - size_t pos = hash % _map_->capacity; - struct hashbidimap_entry *target = _map_->buffer[pos][1]; - while (target != ((void *)0)) - { - if (target != ((void *)1) && _map_->f_val->cmp(target->value, val) == 0) - return &(_map_->buffer[pos % _map_->capacity][1]); - pos++; - target = _map_->buffer[pos % _map_->capacity][1]; - } - return ((void *)0); -} -static struct hashbidimap_entry **hbm_impl_add_entry_to_key(struct hashbidimap *_map_, struct hashbidimap_entry *entry) -{ - struct hashbidimap_entry **to_return = ((void *)0); - size_t hash = _map_->f_key->hash(entry->key); - size_t original_pos = hash % _map_->capacity; - size_t pos = original_pos; - struct hashbidimap_entry **scan = &(_map_->buffer[hash % _map_->capacity][0]); - if (*scan == ((void *)0)) - { - *scan = entry; - entry->ref[0] = scan; - return scan; - } - else - { - while (1) - { - pos++; - scan = &(_map_->buffer[pos % _map_->capacity][0]); - if (*scan == ((void *)0) || *scan == ((void *)1)) - { - if (!to_return) - to_return = scan; - *scan = entry; - entry->ref[0] = scan; - entry->dist[0] = pos - original_pos; - return to_return; - } - else if ((*scan)->dist[0] < pos - original_pos) - { - if (!to_return) - to_return = scan; - size_t tmp_dist = (*scan)->dist[0]; - entry->dist[0] = pos - original_pos; - original_pos = pos - tmp_dist; - entry->ref[0] = scan; - struct hashbidimap_entry *_tmp_ = *scan; - *scan = entry; - entry = _tmp_; - } - } - } - return ((void *)0); -} -static struct hashbidimap_entry **hbm_impl_add_entry_to_val(struct hashbidimap *_map_, struct hashbidimap_entry *entry) -{ - struct hashbidimap_entry **to_return = ((void *)0); - size_t hash = _map_->f_val->hash(entry->value); - size_t original_pos = hash % _map_->capacity; - size_t pos = original_pos; - struct hashbidimap_entry **scan = &(_map_->buffer[hash % _map_->capacity][1]); - if (*scan == ((void *)0)) - { - *scan = entry; - entry->ref[1] = scan; - return scan; - } - else - { - while (1) - { - pos++; - scan = &(_map_->buffer[pos % _map_->capacity][1]); - if (*scan == ((void *)0) || *scan == ((void *)1)) - { - if (!to_return) - to_return = scan; - *scan = entry; - entry->ref[1] = scan; - entry->dist[1] = pos - original_pos; - return to_return; - } - else if ((*scan)->dist[1] < pos - original_pos) - { - if (!to_return) - to_return = scan; - size_t tmp_dist = (*scan)->dist[1]; - entry->dist[1] = pos - original_pos; - original_pos = pos - tmp_dist; - entry->ref[1] = scan; - struct hashbidimap_entry *_tmp_ = *scan; - *scan = entry; - entry = _tmp_; - } - } - } - return ((void *)0); -} -static size_t hbm_impl_calculate_size(size_t required) -{ - const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); - if (cmc_hashtable_primes[count - 1] < required) - return required; - size_t i = 0; - while (cmc_hashtable_primes[i] < required) - i++; - return cmc_hashtable_primes[i]; -} -static struct hashbidimap_iter hbm_impl_it_start(struct hashbidimap *_map_) -{ - struct hashbidimap_iter iter; - hbm_iter_init(&iter, _map_); - return iter; -} -static struct hashbidimap_iter hbm_impl_it_end(struct hashbidimap *_map_) -{ - struct hashbidimap_iter iter; - hbm_iter_init(&iter, _map_); - hbm_iter_to_end(&iter); - return iter; -} -_Bool hbm_to_string(struct hashbidimap *_map_, FILE *fptr) -{ - struct hashbidimap *m_ = _map_; - return 0 <= fprintf(fptr, - "struct %s<%s, %s> " - "at %p { " - "buffer:%p, " - "capacity:%" - "I64u" - ", " - "count:%" - "I64u" - ", " - "load:%lf, " - "flag:%d, " - "f_key:%p, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }", - "hashbidimap", "size_t", "size_t", m_, m_->buffer, m_->capacity, m_->count, m_->load, m_->flag, - m_->f_key, m_->f_val, m_->alloc, (m_)->callbacks); -} -_Bool hbm_print(struct hashbidimap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, - const char *key_val_sep) -{ - fprintf(fptr, "%s", start); - size_t last = 0; - for (size_t i = _map_->capacity; i > 0; i--) - { - struct hashbidimap_entry *entry = _map_->buffer[i - 1][0]; - if (entry && entry != ((void *)1)) - { - last = i - 1; - break; - } - } - for (size_t i = 0; i < _map_->capacity; i++) - { - struct hashbidimap_entry *entry = _map_->buffer[i][0]; - if (entry && entry != ((void *)1)) - { - if (!_map_->f_key->str(fptr, entry->key)) - return 0; - fprintf(fptr, "%s", key_val_sep); - if (!_map_->f_val->str(fptr, entry->value)) - return 0; - if (i + 1 < last) - fprintf(fptr, "%s", separator); - } - } - fprintf(fptr, "%s", end); - return 1; -} diff --git a/tests/src/tst_cmc_hashmap.c b/tests/src/tst_cmc_hashmap.c deleted file mode 100644 index 8135d58..0000000 --- a/tests/src/tst_cmc_hashmap.c +++ /dev/null @@ -1,788 +0,0 @@ - -#include "tst_cmc_hashmap.h" - -static struct hashmap_entry *hm_impl_get_entry(struct hashmap *_map_, size_t key); -static size_t hm_impl_calculate_size(size_t required); -struct hashmap *hm_new(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val) -{ - return hm_new_custom(capacity, load, f_key, f_val, ((void *)0), ((void *)0)); -} -struct hashmap *hm_new_custom(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val, - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (capacity == 0 || load <= 0 || load >= 1) - return ((void *)0); - if (capacity >= 0xffffffffffffffffULL * load) - return ((void *)0); - if (!f_key || !f_val) - return ((void *)0); - size_t real_capacity = hm_impl_calculate_size(capacity / load); - if (!alloc) - alloc = &cmc_alloc_node_default; - struct hashmap *_map_ = alloc->malloc(sizeof(struct hashmap)); - if (!_map_) - return ((void *)0); - _map_->buffer = alloc->calloc(real_capacity, sizeof(struct hashmap_entry)); - if (!_map_->buffer) - { - alloc->free(_map_); - return ((void *)0); - } - _map_->count = 0; - _map_->capacity = real_capacity; - _map_->load = load; - _map_->flag = CMC_FLAG_OK; - _map_->f_key = f_key; - _map_->f_val = f_val; - _map_->alloc = alloc; - (_map_)->callbacks = callbacks; - return _map_; -} -void hm_clear(struct hashmap *_map_) -{ - if (_map_->f_key->free || _map_->f_val->free) - { - for (size_t i = 0; i < _map_->capacity; i++) - { - struct hashmap_entry *entry = &(_map_->buffer[i]); - if (entry->state == CMC_ES_FILLED) - { - if (_map_->f_key->free) - _map_->f_key->free(entry->key); - if (_map_->f_val->free) - _map_->f_val->free(entry->value); - } - } - } - memset(_map_->buffer, 0, sizeof(struct hashmap_entry) * _map_->capacity); - _map_->count = 0; - _map_->flag = CMC_FLAG_OK; -} -void hm_free(struct hashmap *_map_) -{ - if (_map_->f_key->free || _map_->f_val->free) - { - for (size_t i = 0; i < _map_->capacity; i++) - { - struct hashmap_entry *entry = &(_map_->buffer[i]); - if (entry->state == CMC_ES_FILLED) - { - if (_map_->f_key->free) - _map_->f_key->free(entry->key); - if (_map_->f_val->free) - _map_->f_val->free(entry->value); - } - } - } - _map_->alloc->free(_map_->buffer); - _map_->alloc->free(_map_); -} -void hm_customize(struct hashmap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (!alloc) - _map_->alloc = &cmc_alloc_node_default; - else - _map_->alloc = alloc; - (_map_)->callbacks = callbacks; - _map_->flag = CMC_FLAG_OK; -} -_Bool hm_insert(struct hashmap *_map_, size_t key, size_t value) -{ - if (hm_full(_map_)) - { - if (!hm_resize(_map_, _map_->capacity + 1)) - return 0; - } - if (hm_impl_get_entry(_map_, key) != ((void *)0)) - { - _map_->flag = CMC_FLAG_DUPLICATE; - return 0; - } - size_t hash = _map_->f_key->hash(key); - size_t original_pos = hash % _map_->capacity; - size_t pos = original_pos; - struct hashmap_entry *target = &(_map_->buffer[pos]); - if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) - { - target->key = key; - target->value = value; - target->dist = 0; - target->state = CMC_ES_FILLED; - } - else - { - while (1) - { - pos++; - target = &(_map_->buffer[pos % _map_->capacity]); - if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) - { - target->key = key; - target->value = value; - target->dist = pos - original_pos; - target->state = CMC_ES_FILLED; - break; - } - else if (target->dist < pos - original_pos) - { - size_t tmp_k = target->key; - size_t tmp_v = target->value; - size_t tmp_dist = target->dist; - target->key = key; - target->value = value; - target->dist = pos - original_pos; - key = tmp_k; - value = tmp_v; - original_pos = pos - tmp_dist; - } - } - } - _map_->count++; - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->create) - (_map_)->callbacks->create(); - ; - return 1; -} -_Bool hm_update(struct hashmap *_map_, size_t key, size_t new_value, size_t *old_value) -{ - if (hm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct hashmap_entry *entry = hm_impl_get_entry(_map_, key); - if (!entry) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - if (old_value) - *old_value = entry->value; - entry->value = new_value; - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->update) - (_map_)->callbacks->update(); - ; - return 1; -} -_Bool hm_remove(struct hashmap *_map_, size_t key, size_t *out_value) -{ - if (hm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct hashmap_entry *result = hm_impl_get_entry(_map_, key); - if (result == ((void *)0)) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - if (out_value) - *out_value = result->value; - result->key = (size_t){ 0 }; - result->value = (size_t){ 0 }; - result->dist = 0; - result->state = CMC_ES_DELETED; - _map_->count--; - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->delete) - (_map_)->callbacks->delete (); - ; - return 1; -} -_Bool hm_max(struct hashmap *_map_, size_t *key, size_t *value) -{ - if (hm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return 0; - } - _Bool first = 1; - size_t max_key = (size_t){ 0 }; - size_t max_val = (size_t){ 0 }; - for (size_t i = 0; i < _map_->capacity; i++) - { - if (_map_->buffer[i].state == CMC_ES_FILLED) - { - if (first) - { - max_key = _map_->buffer[i].key; - max_val = _map_->buffer[i].value; - first = 0; - } - else if (_map_->f_key->cmp(_map_->buffer[i].key, max_key) > 0) - { - max_key = _map_->buffer[i].key; - max_val = _map_->buffer[i].value; - } - } - } - if (key) - *key = max_key; - if (value) - *value = max_val; - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->read) - (_map_)->callbacks->read(); - ; - return 1; -} -_Bool hm_min(struct hashmap *_map_, size_t *key, size_t *value) -{ - if (hm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return 0; - } - _Bool first = 1; - size_t min_key = (size_t){ 0 }; - size_t min_val = (size_t){ 0 }; - for (size_t i = 0; i < _map_->capacity; i++) - { - if (_map_->buffer[i].state == CMC_ES_FILLED) - { - if (first) - { - min_key = _map_->buffer[i].key; - min_val = _map_->buffer[i].value; - first = 0; - } - else if (_map_->f_key->cmp(_map_->buffer[i].key, min_key) < 0) - { - min_key = _map_->buffer[i].key; - min_val = _map_->buffer[i].value; - } - } - } - if (key) - *key = min_key; - if (value) - *value = min_val; - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->read) - (_map_)->callbacks->read(); - ; - return 1; -} -size_t hm_get(struct hashmap *_map_, size_t key) -{ - if (hm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - struct hashmap_entry *entry = hm_impl_get_entry(_map_, key); - if (!entry) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return (size_t){ 0 }; - } - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->read) - (_map_)->callbacks->read(); - ; - return entry->value; -} -size_t *hm_get_ref(struct hashmap *_map_, size_t key) -{ - if (hm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return ((void *)0); - } - struct hashmap_entry *entry = hm_impl_get_entry(_map_, key); - if (!entry) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return ((void *)0); - } - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->read) - (_map_)->callbacks->read(); - ; - return &(entry->value); -} -_Bool hm_contains(struct hashmap *_map_, size_t key) -{ - _map_->flag = CMC_FLAG_OK; - _Bool result = hm_impl_get_entry(_map_, key) != ((void *)0); - if ((_map_)->callbacks && (_map_)->callbacks->read) - (_map_)->callbacks->read(); - ; - return result; -} -_Bool hm_empty(struct hashmap *_map_) -{ - return _map_->count == 0; -} -_Bool hm_full(struct hashmap *_map_) -{ - return (double)_map_->capacity * _map_->load <= (double)_map_->count; -} -size_t hm_count(struct hashmap *_map_) -{ - return _map_->count; -} -size_t hm_capacity(struct hashmap *_map_) -{ - return _map_->capacity; -} -double hm_load(struct hashmap *_map_) -{ - return _map_->load; -} -int hm_flag(struct hashmap *_map_) -{ - return _map_->flag; -} -_Bool hm_resize(struct hashmap *_map_, size_t capacity) -{ - _map_->flag = CMC_FLAG_OK; - if (_map_->capacity == capacity) - goto success; - if (_map_->capacity > capacity / _map_->load) - goto success; - if (capacity >= 0xffffffffffffffffULL * _map_->load) - { - _map_->flag = CMC_FLAG_ERROR; - return 0; - } - size_t theoretical_size = hm_impl_calculate_size(capacity); - if (theoretical_size < _map_->count / _map_->load) - { - _map_->flag = CMC_FLAG_INVALID; - return 0; - } - struct hashmap *_new_map_ = - hm_new_custom(capacity, _map_->load, _map_->f_key, _map_->f_val, _map_->alloc, ((void *)0)); - if (!_new_map_) - { - _map_->flag = CMC_FLAG_ALLOC; - return 0; - } - for (size_t i = 0; i < _map_->capacity; i++) - { - if (_map_->buffer[i].state == CMC_ES_FILLED) - { - size_t key = _map_->buffer[i].key; - size_t value = _map_->buffer[i].value; - hm_insert(_new_map_, key, value); - } - } - if (_map_->count != _new_map_->count) - { - hm_free(_new_map_); - _map_->flag = CMC_FLAG_ERROR; - return 0; - } - struct hashmap_entry *tmp_b = _map_->buffer; - _map_->buffer = _new_map_->buffer; - _new_map_->buffer = tmp_b; - size_t tmp_c = _map_->capacity; - _map_->capacity = _new_map_->capacity; - _new_map_->capacity = tmp_c; - _new_map_->f_key = &(struct hashmap_fkey){ ((void *)0) }; - _new_map_->f_val = &(struct hashmap_fval){ ((void *)0) }; - hm_free(_new_map_); -success: - if ((_map_)->callbacks && (_map_)->callbacks->resize) - (_map_)->callbacks->resize(); - ; - return 1; -} -struct hashmap *hm_copy_of(struct hashmap *_map_) -{ - struct hashmap *result = hm_new_custom(_map_->capacity * _map_->load, _map_->load, _map_->f_key, _map_->f_val, - _map_->alloc, ((void *)0)); - if (!result) - { - _map_->flag = CMC_FLAG_ERROR; - return ((void *)0); - } - (result)->callbacks = _map_->callbacks; - if (_map_->f_key->cpy || _map_->f_val->cpy) - { - for (size_t i = 0; i < _map_->capacity; i++) - { - struct hashmap_entry *scan = &(_map_->buffer[i]); - if (scan->state != CMC_ES_EMPTY) - { - struct hashmap_entry *target = &(result->buffer[i]); - if (scan->state == CMC_ES_DELETED) - target->state = CMC_ES_DELETED; - else - { - target->state = scan->state; - target->dist = scan->dist; - if (_map_->f_key->cpy) - target->key = _map_->f_key->cpy(scan->key); - else - target->key = scan->key; - if (_map_->f_val->cpy) - target->value = _map_->f_val->cpy(scan->value); - else - target->value = scan->value; - } - } - } - } - else - memcpy(result->buffer, _map_->buffer, sizeof(struct hashmap_entry) * _map_->capacity); - result->count = _map_->count; - _map_->flag = CMC_FLAG_OK; - return result; -} -_Bool hm_equals(struct hashmap *_map1_, struct hashmap *_map2_) -{ - _map1_->flag = CMC_FLAG_OK; - _map2_->flag = CMC_FLAG_OK; - if (_map1_->count != _map2_->count) - return 0; - struct hashmap *_map_a_; - struct hashmap *_map_b_; - _map_a_ = _map1_->capacity < _map2_->capacity ? _map1_ : _map2_; - _map_b_ = _map_a_ == _map1_ ? _map2_ : _map1_; - for (size_t i = 0; i < _map_a_->capacity; i++) - { - if (_map_a_->buffer[i].state == CMC_ES_FILLED) - { - struct hashmap_entry *entry_a = &(_map_a_->buffer[i]); - struct hashmap_entry *entry_b = hm_impl_get_entry(_map_b_, entry_a->key); - if (!entry_b) - return 0; - if (_map_a_->f_val->cmp(entry_a->value, entry_b->value) != 0) - return 0; - } - } - return 1; -} -static struct hashmap_entry *hm_impl_get_entry(struct hashmap *_map_, size_t key) -{ - size_t hash = _map_->f_key->hash(key); - size_t pos = hash % _map_->capacity; - struct hashmap_entry *target = &(_map_->buffer[pos]); - while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED) - { - if (_map_->f_key->cmp(target->key, key) == 0) - return target; - pos++; - target = &(_map_->buffer[pos % _map_->capacity]); - } - return ((void *)0); -} -static size_t hm_impl_calculate_size(size_t required) -{ - const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); - if (cmc_hashtable_primes[count - 1] < required) - return required; - size_t i = 0; - while (cmc_hashtable_primes[i] < required) - i++; - return cmc_hashtable_primes[i]; -} -struct hashmap hm_init(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val) -{ - return hm_init_custom(capacity, load, f_key, f_val, ((void *)0), ((void *)0)); -} -struct hashmap hm_init_custom(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val, - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - struct hashmap _map_ = { 0 }; - if (capacity == 0 || load <= 0 || load >= 1) - return _map_; - if (capacity >= 0xffffffffffffffffULL * load) - return _map_; - if (!f_key || !f_val) - return _map_; - size_t real_capacity = hm_impl_calculate_size(capacity / load); - if (!alloc) - alloc = &cmc_alloc_node_default; - _map_.buffer = alloc->calloc(real_capacity, sizeof(struct hashmap_entry)); - if (!_map_.buffer) - return _map_; - _map_.count = 0; - _map_.capacity = real_capacity; - _map_.load = load; - _map_.flag = CMC_FLAG_OK; - _map_.f_key = f_key; - _map_.f_val = f_val; - _map_.alloc = alloc; - (&_map_)->callbacks = callbacks; - return _map_; -} -void hm_release(struct hashmap _map_) -{ - if (_map_.f_key->free || _map_.f_val->free) - { - for (size_t i = 0; i < _map_.capacity; i++) - { - struct hashmap_entry *entry = &(_map_.buffer[i]); - if (entry->state == CMC_ES_FILLED) - { - if (_map_.f_key->free) - _map_.f_key->free(entry->key); - if (_map_.f_val->free) - _map_.f_val->free(entry->value); - } - } - } - _map_.alloc->free(_map_.buffer); -} -struct hashmap_iter hm_iter_start(struct hashmap *target) -{ - struct hashmap_iter iter; - iter.target = target; - iter.cursor = 0; - iter.index = 0; - iter.first = 0; - iter.last = 0; - iter.start = 1; - iter.end = hm_empty(target); - if (!hm_empty(target)) - { - for (size_t i = 0; i < target->capacity; i++) - { - if (target->buffer[i].state == CMC_ES_FILLED) - { - iter.first = i; - break; - } - } - iter.cursor = iter.first; - for (size_t i = target->capacity; i > 0; i--) - { - if (target->buffer[i - 1].state == CMC_ES_FILLED) - { - iter.last = i - 1; - break; - } - } - } - return iter; -} -struct hashmap_iter hm_iter_end(struct hashmap *target) -{ - struct hashmap_iter iter; - iter.target = target; - iter.cursor = 0; - iter.index = 0; - iter.first = 0; - iter.last = 0; - iter.start = hm_empty(target); - iter.end = 1; - if (!hm_empty(target)) - { - for (size_t i = 0; i < target->capacity; i++) - { - if (target->buffer[i].state == CMC_ES_FILLED) - { - iter.first = i; - break; - } - } - for (size_t i = target->capacity; i > 0; i--) - { - if (target->buffer[i - 1].state == CMC_ES_FILLED) - { - iter.last = i - 1; - break; - } - } - iter.cursor = iter.last; - iter.index = target->count - 1; - } - return iter; -} -_Bool hm_iter_at_start(struct hashmap_iter *iter) -{ - return hm_empty(iter->target) || iter->start; -} -_Bool hm_iter_at_end(struct hashmap_iter *iter) -{ - return hm_empty(iter->target) || iter->end; -} -_Bool hm_iter_to_start(struct hashmap_iter *iter) -{ - if (!hm_empty(iter->target)) - { - iter->cursor = iter->first; - iter->index = 0; - iter->start = 1; - iter->end = hm_empty(iter->target); - return 1; - } - return 0; -} -_Bool hm_iter_to_end(struct hashmap_iter *iter) -{ - if (!hm_empty(iter->target)) - { - iter->cursor = iter->last; - iter->index = iter->target->count - 1; - iter->start = hm_empty(iter->target); - iter->end = 1; - return 1; - } - return 0; -} -_Bool hm_iter_next(struct hashmap_iter *iter) -{ - if (iter->end) - return 0; - if (iter->index + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - iter->start = hm_empty(iter->target); - struct hashmap_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 1; -} -_Bool hm_iter_prev(struct hashmap_iter *iter) -{ - if (iter->start) - return 0; - if (iter->index == 0) - { - iter->start = 1; - return 0; - } - iter->end = hm_empty(iter->target); - struct hashmap_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 1; -} -_Bool hm_iter_advance(struct hashmap_iter *iter, size_t steps) -{ - if (iter->end) - return 0; - if (iter->index + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - if (steps == 0 || iter->index + steps >= iter->target->count) - return 0; - for (size_t i = 0; i < steps; i++) - hm_iter_next(iter); - return 1; -} -_Bool hm_iter_rewind(struct hashmap_iter *iter, size_t steps) -{ - if (iter->start) - return 0; - if (iter->index == 0) - { - iter->start = 1; - return 0; - } - if (steps == 0 || iter->index < steps) - return 0; - for (size_t i = 0; i < steps; i++) - hm_iter_prev(iter); - return 1; -} -_Bool hm_iter_go_to(struct hashmap_iter *iter, size_t index) -{ - if (index >= iter->target->count) - return 0; - if (iter->index > index) - return hm_iter_rewind(iter, iter->index - index); - else if (iter->index < index) - return hm_iter_advance(iter, index - iter->index); - return 1; -} -size_t hm_iter_key(struct hashmap_iter *iter) -{ - if (hm_empty(iter->target)) - return (size_t){ 0 }; - return iter->target->buffer[iter->cursor].key; -} -size_t hm_iter_value(struct hashmap_iter *iter) -{ - if (hm_empty(iter->target)) - return (size_t){ 0 }; - return iter->target->buffer[iter->cursor].value; -} -size_t *hm_iter_rvalue(struct hashmap_iter *iter) -{ - if (hm_empty(iter->target)) - return ((void *)0); - return &(iter->target->buffer[iter->cursor].value); -} -size_t hm_iter_index(struct hashmap_iter *iter) -{ - return iter->index; -} -_Bool hm_to_string(struct hashmap *_map_, FILE *fptr) -{ - struct hashmap *m_ = _map_; - return 0 <= fprintf(fptr, - "struct %s<%s, %s> " - "at %p { " - "buffer:%p, " - "capacity:%" - "I64u" - ", " - "count:%" - "I64u" - ", " - "load:%lf, " - "flag:%d, " - "f_key:%p, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }", - "hashmap", "size_t", "size_t", m_, m_->buffer, m_->capacity, m_->count, m_->load, m_->flag, - m_->f_key, m_->f_val, m_->alloc, (m_)->callbacks); -} -_Bool hm_print(struct hashmap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, - const char *key_val_sep) -{ - fprintf(fptr, "%s", start); - size_t last = 0; - for (size_t i = _map_->capacity; i > 0; i--) - { - if ((_map_->buffer[i - 1]).state == CMC_ES_FILLED) - { - last = i - 1; - break; - } - } - for (size_t i = 0; i < _map_->capacity; i++) - { - struct hashmap_entry *entry = &(_map_->buffer[i]); - if (entry->state == CMC_ES_FILLED) - { - if (!_map_->f_key->str(fptr, entry->key)) - return 0; - fprintf(fptr, "%s", key_val_sep); - if (!_map_->f_val->str(fptr, entry->value)) - return 0; - if (i + 1 < last) - fprintf(fptr, "%s", separator); - } - } - fprintf(fptr, "%s", end); - return 1; -} diff --git a/tests/src/tst_cmc_hashmultimap.c b/tests/src/tst_cmc_hashmultimap.c deleted file mode 100644 index 79177d4..0000000 --- a/tests/src/tst_cmc_hashmultimap.c +++ /dev/null @@ -1,931 +0,0 @@ - -#include "tst_cmc_hashmultimap.h" - -struct hashmultimap_entry *hmm_impl_new_entry(struct hashmultimap *_map_, size_t key, size_t value); -struct hashmultimap_entry *hmm_impl_get_entry(struct hashmultimap *_map_, size_t key); -size_t hmm_impl_key_count(struct hashmultimap *_map_, size_t key); -size_t hmm_impl_calculate_size(size_t required); -struct hashmultimap *hmm_new(size_t capacity, double load, struct hashmultimap_fkey *f_key, - struct hashmultimap_fval *f_val) -{ - return hmm_new_custom(capacity, load, f_key, f_val, ((void *)0), ((void *)0)); -} -struct hashmultimap *hmm_new_custom(size_t capacity, double load, struct hashmultimap_fkey *f_key, - struct hashmultimap_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) -{ - ; - if (capacity == 0 || load <= 0) - return ((void *)0); - if (capacity >= 0xffffffffffffffffULL * load) - return ((void *)0); - if (!f_key || !f_val) - return ((void *)0); - if (!alloc) - alloc = &cmc_alloc_node_default; - size_t real_capacity = hmm_impl_calculate_size(capacity / load); - struct hashmultimap *_map_ = alloc->malloc(sizeof(struct hashmultimap)); - if (!_map_) - return ((void *)0); - _map_->buffer = alloc->calloc(real_capacity, sizeof(struct hashmultimap_entry *[2])); - if (!_map_->buffer) - { - alloc->free(_map_); - return ((void *)0); - } - _map_->count = 0; - _map_->capacity = real_capacity; - _map_->load = load; - _map_->flag = CMC_FLAG_OK; - _map_->f_key = f_key; - _map_->f_val = f_val; - _map_->alloc = alloc; - (_map_)->callbacks = callbacks; - return _map_; -} -void hmm_clear(struct hashmultimap *_map_) -{ - for (size_t i = 0; i < _map_->capacity; i++) - { - struct hashmultimap_entry *scan = _map_->buffer[i][0]; - while (scan) - { - struct hashmultimap_entry *next = scan->next; - if (_map_->f_key->free) - _map_->f_key->free(scan->key); - if (_map_->f_val->free) - _map_->f_val->free(scan->value); - _map_->alloc->free(scan); - scan = next; - } - } - memset(_map_->buffer, 0, sizeof(struct hashmultimap_entry *[2]) * _map_->capacity); - _map_->count = 0; - _map_->flag = CMC_FLAG_OK; -} -void hmm_free(struct hashmultimap *_map_) -{ - size_t index = 0; - while (index < _map_->capacity) - { - struct hashmultimap_entry *scan = _map_->buffer[index][0]; - if (scan) - { - if (scan->next == ((void *)0) && scan->prev == ((void *)0)) - { - if (_map_->f_key->free) - _map_->f_key->free(scan->key); - if (_map_->f_val->free) - _map_->f_val->free(scan->value); - _map_->alloc->free(scan); - } - else - { - while (scan) - { - struct hashmultimap_entry *tmp = scan; - scan = scan->next; - if (_map_->f_key->free) - _map_->f_key->free(tmp->key); - if (_map_->f_val->free) - _map_->f_val->free(tmp->value); - _map_->alloc->free(tmp); - } - } - } - index++; - } - _map_->alloc->free(_map_->buffer); - _map_->alloc->free(_map_); -} -void hmm_customize(struct hashmultimap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (!alloc) - _map_->alloc = &cmc_alloc_node_default; - else - _map_->alloc = alloc; - (_map_)->callbacks = callbacks; - _map_->flag = CMC_FLAG_OK; -} -_Bool hmm_insert(struct hashmultimap *_map_, size_t key, size_t value) -{ - if (hmm_full(_map_)) - { - if (!hmm_resize(_map_, _map_->capacity + 1)) - return 0; - } - size_t hash = _map_->f_key->hash(key); - size_t pos = hash % _map_->capacity; - struct hashmultimap_entry *entry = hmm_impl_new_entry(_map_, key, value); - if (_map_->buffer[pos][0] == ((void *)0)) - { - _map_->buffer[pos][0] = entry; - _map_->buffer[pos][1] = entry; - } - else - { - entry->prev = _map_->buffer[pos][1]; - _map_->buffer[pos][1]->next = entry; - _map_->buffer[pos][1] = entry; - } - _map_->count++; - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->create) - (_map_)->callbacks->create(); - ; - return 1; -} -_Bool hmm_update(struct hashmultimap *_map_, size_t key, size_t new_value, size_t *old_value) -{ - if (hmm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct hashmultimap_entry *entry = hmm_impl_get_entry(_map_, key); - if (!entry) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - if (old_value) - *old_value = entry->value; - entry->value = new_value; - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->update) - (_map_)->callbacks->update(); - ; - return 1; -} -size_t hmm_update_all(struct hashmultimap *_map_, size_t key, size_t new_value, size_t **old_values) -{ - if (hmm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return 0; - } - size_t hash = _map_->f_key->hash(key); - struct hashmultimap_entry *entry = _map_->buffer[hash % _map_->capacity][0]; - if (entry == ((void *)0)) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - if (old_values) - { - size_t total = hmm_impl_key_count(_map_, key); - if (total == 0) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - *old_values = _map_->alloc->malloc(sizeof(size_t) * total); - if (!(*old_values)) - { - _map_->flag = CMC_FLAG_ALLOC; - return 0; - } - } - size_t index = 0; - while (entry) - { - if (_map_->f_key->cmp(entry->key, key) == 0) - { - if (old_values) - (*old_values)[index] = entry->value; - index++; - entry->value = new_value; - } - entry = entry->next; - } - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->update) - (_map_)->callbacks->update(); - ; - return index; -} -_Bool hmm_remove(struct hashmultimap *_map_, size_t key, size_t *out_value) -{ - if (hmm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return 0; - } - size_t hash = _map_->f_key->hash(key); - struct hashmultimap_entry **head = &(_map_->buffer[hash % _map_->capacity][0]); - struct hashmultimap_entry **tail = &(_map_->buffer[hash % _map_->capacity][1]); - if (*head == ((void *)0)) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - struct hashmultimap_entry *entry = *head; - if (entry->next == ((void *)0) && entry->prev == ((void *)0)) - { - if (_map_->f_key->cmp(entry->key, key) == 0) - { - *head = ((void *)0); - *tail = ((void *)0); - if (out_value) - *out_value = entry->value; - } - else - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - } - else - { - _Bool found = 0; - while (entry) - { - if (_map_->f_key->cmp(entry->key, key) == 0) - { - if (*head == entry) - *head = entry->next; - if (*tail == entry) - *tail = entry->prev; - if (entry->prev) - entry->prev->next = entry->next; - if (entry->next) - entry->next->prev = entry->prev; - if (out_value) - *out_value = entry->value; - found = 1; - break; - } - else - entry = entry->next; - } - if (!found) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - } - _map_->alloc->free(entry); - _map_->count--; - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->delete) - (_map_)->callbacks->delete (); - ; - return 1; -} -size_t hmm_remove_all(struct hashmultimap *_map_, size_t key, size_t **out_values) -{ - if (hmm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return 0; - } - size_t hash = _map_->f_key->hash(key); - struct hashmultimap_entry **head = &(_map_->buffer[hash % _map_->capacity][0]); - struct hashmultimap_entry **tail = &(_map_->buffer[hash % _map_->capacity][1]); - if (*head == ((void *)0)) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - if (out_values) - { - size_t total = hmm_impl_key_count(_map_, key); - if (total == 0) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - *out_values = _map_->alloc->malloc(sizeof(size_t) * total); - if (!(*out_values)) - { - _map_->flag = CMC_FLAG_ALLOC; - return 0; - } - } - size_t index = 0; - struct hashmultimap_entry *entry = *head; - if (entry->next == ((void *)0)) - { - *head = ((void *)0); - *tail = ((void *)0); - if (out_values) - (*out_values)[index] = entry->value; - index++; - _map_->alloc->free(entry); - } - else - { - while (entry) - { - if (_map_->f_key->cmp(entry->key, key) == 0) - { - if (*head == entry) - *head = entry->next; - if (*tail == entry) - *tail = entry->prev; - struct hashmultimap_entry *next = entry->next; - if (entry->prev) - entry->prev->next = entry->next; - if (entry->next) - entry->next->prev = entry->prev; - if (out_values) - (*out_values)[index] = entry->value; - index++; - _map_->alloc->free(entry); - entry = next; - } - else - entry = entry->next; - } - } - _map_->count -= index; - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->delete) - (_map_)->callbacks->delete (); - ; - return index; -} -_Bool hmm_max(struct hashmultimap *_map_, size_t *key, size_t *value) -{ - if (hmm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return 0; - } - _Bool first = 1; - size_t max_key = (size_t){ 0 }; - size_t max_val = (size_t){ 0 }; - for (size_t i = 0; i < _map_->capacity; i++) - { - struct hashmultimap_entry *scan = _map_->buffer[i][0]; - while (scan) - { - if (first) - { - max_key = scan->key; - max_val = scan->value; - first = 0; - } - else if (_map_->f_key->cmp(scan->key, max_key) > 0) - { - max_key = scan->key; - max_val = scan->value; - } - scan = scan->next; - } - } - if (key) - *key = max_key; - if (value) - *value = max_val; - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->read) - (_map_)->callbacks->read(); - ; - return 1; -} -_Bool hmm_min(struct hashmultimap *_map_, size_t *key, size_t *value) -{ - if (hmm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return 0; - } - _Bool first = 1; - size_t min_key = (size_t){ 0 }; - size_t min_val = (size_t){ 0 }; - for (size_t i = 0; i < _map_->capacity; i++) - { - struct hashmultimap_entry *scan = _map_->buffer[i][0]; - while (scan) - { - if (first) - { - min_key = scan->key; - min_val = scan->value; - first = 0; - } - else if (_map_->f_key->cmp(scan->key, min_key) < 0) - { - min_key = scan->key; - min_val = scan->value; - } - scan = scan->next; - } - } - if (key) - *key = min_key; - if (value) - *value = min_val; - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->read) - (_map_)->callbacks->read(); - ; - return 1; -} -size_t hmm_get(struct hashmultimap *_map_, size_t key) -{ - if (hmm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - struct hashmultimap_entry *entry = hmm_impl_get_entry(_map_, key); - if (!entry) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return (size_t){ 0 }; - } - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->read) - (_map_)->callbacks->read(); - ; - return entry->value; -} -size_t *hmm_get_ref(struct hashmultimap *_map_, size_t key) -{ - if (hmm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return ((void *)0); - } - struct hashmultimap_entry *entry = hmm_impl_get_entry(_map_, key); - if (!entry) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return ((void *)0); - } - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->read) - (_map_)->callbacks->read(); - ; - return &(entry->value); -} -_Bool hmm_contains(struct hashmultimap *_map_, size_t key) -{ - _map_->flag = CMC_FLAG_OK; - _Bool result = hmm_impl_get_entry(_map_, key) != ((void *)0); - if ((_map_)->callbacks && (_map_)->callbacks->read) - (_map_)->callbacks->read(); - ; - return result; -} -_Bool hmm_empty(struct hashmultimap *_map_) -{ - return _map_->count == 0; -} -_Bool hmm_full(struct hashmultimap *_map_) -{ - return (double)_map_->capacity * _map_->load <= (double)_map_->count; -} -size_t hmm_count(struct hashmultimap *_map_) -{ - return _map_->count; -} -size_t hmm_key_count(struct hashmultimap *_map_, size_t key) -{ - return hmm_impl_key_count(_map_, key); -} -size_t hmm_capacity(struct hashmultimap *_map_) -{ - return _map_->capacity; -} -double hmm_load(struct hashmultimap *_map_) -{ - return _map_->load; -} -int hmm_flag(struct hashmultimap *_map_) -{ - return _map_->flag; -} -_Bool hmm_resize(struct hashmultimap *_map_, size_t capacity) -{ - _map_->flag = CMC_FLAG_OK; - if (_map_->capacity == capacity) - goto success; - if (_map_->capacity > capacity / _map_->load) - goto success; - if (capacity >= 0xffffffffffffffffULL * _map_->load) - { - _map_->flag = CMC_FLAG_ERROR; - return 0; - } - size_t theoretical_size = hmm_impl_calculate_size(capacity); - if (theoretical_size < _map_->count / _map_->load) - { - _map_->flag = CMC_FLAG_INVALID; - return 0; - } - struct hashmultimap *_new_map_ = - hmm_new_custom(capacity, _map_->load, _map_->f_key, _map_->f_val, _map_->alloc, ((void *)0)); - if (!_new_map_) - { - _map_->flag = CMC_FLAG_ALLOC; - return 0; - } - for (size_t i = 0; i < _map_->capacity; i++) - { - struct hashmultimap_entry *scan = _map_->buffer[i][0]; - while (scan) - { - hmm_insert(_new_map_, scan->key, scan->value); - scan = scan->next; - } - } - if (_map_->count != _new_map_->count) - { - hmm_free(_new_map_); - _map_->flag = CMC_FLAG_ERROR; - return 0; - } - struct hashmultimap_entry *(*tmp_b)[2] = _map_->buffer; - _map_->buffer = _new_map_->buffer; - _new_map_->buffer = tmp_b; - size_t tmp_c = _map_->capacity; - _map_->capacity = _new_map_->capacity; - _new_map_->capacity = tmp_c; - _new_map_->f_key = &(struct hashmultimap_fkey){ ((void *)0) }; - _new_map_->f_val = &(struct hashmultimap_fval){ ((void *)0) }; - hmm_free(_new_map_); -success: - if ((_map_)->callbacks && (_map_)->callbacks->resize) - (_map_)->callbacks->resize(); - ; - return 1; -} -struct hashmultimap *hmm_copy_of(struct hashmultimap *_map_) -{ - struct hashmultimap *result = hmm_new_custom(_map_->capacity * _map_->load, _map_->load, _map_->f_key, _map_->f_val, - _map_->alloc, ((void *)0)); - if (!result) - { - _map_->flag = CMC_FLAG_ERROR; - return ((void *)0); - } - for (size_t i = 0; i < _map_->capacity; i++) - { - struct hashmultimap_entry *scan = _map_->buffer[i][0]; - while (scan) - { - size_t key; - size_t value; - if (_map_->f_key->cpy) - key = _map_->f_key->cpy(scan->key); - else - key = scan->key; - if (_map_->f_val->cpy) - value = _map_->f_val->cpy(scan->value); - else - value = scan->value; - hmm_insert(result, key, value); - scan = scan->next; - } - } - (result)->callbacks = _map_->callbacks; - _map_->flag = CMC_FLAG_OK; - return result; -} -_Bool hmm_equals(struct hashmultimap *_map1_, struct hashmultimap *_map2_) -{ - _map1_->flag = CMC_FLAG_OK; - _map2_->flag = CMC_FLAG_OK; - if (_map1_->count != _map2_->count) - return 0; - struct hashmultimap *_map_a_; - struct hashmultimap *_map_b_; - _map_a_ = _map1_->capacity < _map2_->capacity ? _map1_ : _map2_; - _map_b_ = _map_a_ == _map1_ ? _map2_ : _map1_; - for (size_t i = 0; i < _map_a_->capacity; i++) - { - struct hashmultimap_entry *scan = _map_a_->buffer[i][0]; - while (scan) - { - if (hmm_impl_key_count(_map_a_, scan->key) != hmm_impl_key_count(_map_b_, scan->key)) - return 0; - scan = scan->next; - } - } - return 1; -} -struct hashmultimap_entry *hmm_impl_new_entry(struct hashmultimap *_map_, size_t key, size_t value) -{ - struct hashmultimap_entry *entry = _map_->alloc->malloc(sizeof(struct hashmultimap_entry)); - if (!entry) - return ((void *)0); - entry->key = key; - entry->value = value; - entry->next = ((void *)0); - entry->prev = ((void *)0); - return entry; -} -struct hashmultimap_entry *hmm_impl_get_entry(struct hashmultimap *_map_, size_t key) -{ - size_t hash = _map_->f_key->hash(key); - struct hashmultimap_entry *entry = _map_->buffer[hash % _map_->capacity][0]; - while (entry) - { - if (_map_->f_key->cmp(entry->key, key) == 0) - return entry; - entry = entry->next; - } - return ((void *)0); -} -size_t hmm_impl_key_count(struct hashmultimap *_map_, size_t key) -{ - size_t hash = _map_->f_key->hash(key); - struct hashmultimap_entry *entry = _map_->buffer[hash % _map_->capacity][0]; - size_t total_count = 0; - if (!entry) - return total_count; - while (entry) - { - if (_map_->f_key->cmp(entry->key, key) == 0) - total_count++; - entry = entry->next; - } - return total_count; -} -size_t hmm_impl_calculate_size(size_t required) -{ - const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); - if (cmc_hashtable_primes[count - 1] < required) - return required; - size_t i = 0; - while (cmc_hashtable_primes[i] < required) - i++; - return cmc_hashtable_primes[i]; -} -struct hashmultimap_iter hmm_iter_start(struct hashmultimap *target) -{ - struct hashmultimap_iter iter; - iter.target = target; - iter.curr_entry = ((void *)0); - iter.cursor = 0; - iter.index = 0; - iter.first = 0; - iter.last = 0; - iter.start = 1; - iter.end = hmm_empty(target); - if (!hmm_empty(target)) - { - for (size_t i = 0; i < target->capacity; i++) - { - struct hashmultimap_entry *entry = target->buffer[i][0]; - if (entry && entry != ((void *)1)) - { - iter.curr_entry = target->buffer[i][0]; - iter.first = i; - break; - } - } - iter.cursor = iter.first; - for (size_t i = target->capacity; i > 0; i--) - { - struct hashmultimap_entry *entry = target->buffer[i - 1][1]; - if (entry && entry != ((void *)1)) - { - iter.last = i - 1; - break; - } - } - } - return iter; -} -struct hashmultimap_iter hmm_iter_end(struct hashmultimap *target) -{ - struct hashmultimap_iter iter; - iter.target = target; - iter.curr_entry = ((void *)0); - iter.cursor = 0; - iter.index = 0; - iter.first = 0; - iter.last = 0; - iter.start = hmm_empty(target); - iter.end = 1; - if (!hmm_empty(target)) - { - for (size_t i = 0; i < target->capacity; i++) - { - struct hashmultimap_entry *entry = target->buffer[i][0]; - if (entry && entry != ((void *)1)) - { - iter.first = i; - break; - } - } - for (size_t i = target->capacity; i > 0; i--) - { - struct hashmultimap_entry *entry = target->buffer[i - 1][1]; - if (entry && entry != ((void *)1)) - { - iter.curr_entry = target->buffer[i - 1][1]; - iter.last = i - 1; - break; - } - } - iter.cursor = iter.last; - iter.index = target->count - 1; - } - return iter; -} -_Bool hmm_iter_at_start(struct hashmultimap_iter *iter) -{ - return hmm_empty(iter->target) || iter->start; -} -_Bool hmm_iter_at_end(struct hashmultimap_iter *iter) -{ - return hmm_empty(iter->target) || iter->end; -} -_Bool hmm_iter_to_start(struct hashmultimap_iter *iter) -{ - if (!hmm_empty(iter->target)) - { - iter->cursor = iter->first; - iter->index = 0; - iter->start = 1; - iter->end = hmm_empty(iter->target); - iter->curr_entry = iter->target->buffer[iter->first][0]; - return 1; - } - return 0; -} -_Bool hmm_iter_to_end(struct hashmultimap_iter *iter) -{ - if (!hmm_empty(iter->target)) - { - iter->cursor = iter->last; - iter->index = iter->target->count - 1; - iter->start = hmm_empty(iter->target); - iter->end = 1; - iter->curr_entry = iter->target->buffer[iter->last][1]; - return 1; - } - return 0; -} -_Bool hmm_iter_next(struct hashmultimap_iter *iter) -{ - if (iter->end) - return 0; - if (iter->curr_entry->next != ((void *)0)) - { - iter->curr_entry = iter->curr_entry->next; - iter->index++; - } - else - { - if (iter->cursor == iter->last) - { - iter->end = 1; - return 0; - } - iter->cursor++; - while (iter->target->buffer[iter->cursor][0] == ((void *)0)) - iter->cursor++; - iter->curr_entry = iter->target->buffer[iter->cursor][0]; - iter->index++; - } - iter->start = hmm_empty(iter->target); - return 1; -} -_Bool hmm_iter_prev(struct hashmultimap_iter *iter) -{ - if (iter->start) - return 0; - if (iter->curr_entry->prev != ((void *)0)) - { - iter->curr_entry = iter->curr_entry->prev; - iter->index--; - } - else - { - if (iter->cursor == iter->first) - { - iter->start = 1; - return 0; - } - iter->cursor--; - while (iter->target->buffer[iter->cursor][1] == ((void *)0)) - iter->cursor--; - iter->curr_entry = iter->target->buffer[iter->cursor][1]; - iter->index--; - } - iter->end = hmm_empty(iter->target); - return 1; -} -_Bool hmm_iter_advance(struct hashmultimap_iter *iter, size_t steps) -{ - if (iter->end) - return 0; - if (iter->index + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - if (steps == 0 || iter->index + steps >= iter->target->count) - return 0; - for (size_t i = 0; i < steps; i++) - hmm_iter_next(iter); - return 1; -} -_Bool hmm_iter_rewind(struct hashmultimap_iter *iter, size_t steps) -{ - if (iter->start) - return 0; - if (iter->index == 0) - { - iter->start = 1; - return 0; - } - if (steps == 0 || iter->index < steps) - return 0; - for (size_t i = 0; i < steps; i++) - hmm_iter_prev(iter); - return 1; -} -_Bool hmm_iter_go_to(struct hashmultimap_iter *iter, size_t index) -{ - if (index >= iter->target->count) - return 0; - if (iter->index > index) - return hmm_iter_rewind(iter, iter->index - index); - else if (iter->index < index) - return hmm_iter_advance(iter, index - iter->index); - return 1; -} -size_t hmm_iter_key(struct hashmultimap_iter *iter) -{ - if (hmm_empty(iter->target)) - return (size_t){ 0 }; - return iter->curr_entry->key; -} -size_t hmm_iter_value(struct hashmultimap_iter *iter) -{ - if (hmm_empty(iter->target)) - return (size_t){ 0 }; - return iter->curr_entry->value; -} -size_t *hmm_iter_rvalue(struct hashmultimap_iter *iter) -{ - if (hmm_empty(iter->target)) - return ((void *)0); - return &(iter->curr_entry->value); -} -size_t hmm_iter_index(struct hashmultimap_iter *iter) -{ - return iter->index; -} -_Bool hmm_to_string(struct hashmultimap *_map_, FILE *fptr) -{ - struct hashmultimap *m_ = _map_; - return 0 <= fprintf(fptr, - "struct %s<%s, %s> " - "at %p { " - "buffer:%p, " - "capacity:%" - "I64u" - ", " - "count:%" - "I64u" - ", " - "load:%lf, " - "flag:%d, " - "f_key:%p, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }", - "hashmultimap", "size_t", "size_t", m_, m_->buffer, m_->capacity, m_->count, m_->load, m_->flag, - m_->f_key, m_->f_val, m_->alloc, (m_)->callbacks); -} -_Bool hmm_print(struct hashmultimap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, - const char *key_val_sep) -{ - fprintf(fptr, "%s", start); - size_t last = 0; - for (size_t i = _map_->capacity; i > 0; i--) - { - struct hashmultimap_entry *entry = _map_->buffer[i - 1][1]; - if (entry && entry != ((void *)1)) - { - last = i - 1; - break; - } - } - for (size_t i = 0; i < _map_->capacity; i++) - { - struct hashmultimap_entry *scan = _map_->buffer[i][0]; - while (scan != ((void *)0)) - { - if (!_map_->f_key->str(fptr, scan->key)) - return 0; - fprintf(fptr, "%s", key_val_sep); - if (!_map_->f_val->str(fptr, scan->value)) - return 0; - scan = scan->next; - if (i + 1 < last) - fprintf(fptr, "%s", separator); - } - } - fprintf(fptr, "%s", end); - return 1; -} diff --git a/tests/src/tst_cmc_hashmultiset.c b/tests/src/tst_cmc_hashmultiset.c deleted file mode 100644 index d10d4b8..0000000 --- a/tests/src/tst_cmc_hashmultiset.c +++ /dev/null @@ -1,972 +0,0 @@ - -#include "tst_cmc_hashmultiset.h" - -static size_t hms_impl_multiplicity_of(struct hashmultiset *_set_, size_t value); -static struct hashmultiset_entry *hms_impl_insert_and_return(struct hashmultiset *_set_, size_t value, _Bool *new_node); -static struct hashmultiset_entry *hms_impl_get_entry(struct hashmultiset *_set_, size_t value); -static size_t hms_impl_calculate_size(size_t required); -struct hashmultiset *hms_new(size_t capacity, double load, struct hashmultiset_fval *f_val) -{ - return hms_new_custom(capacity, load, f_val, ((void *)0), ((void *)0)); -} -struct hashmultiset *hms_new_custom(size_t capacity, double load, struct hashmultiset_fval *f_val, - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (capacity == 0 || load <= 0 || load >= 1) - return ((void *)0); - if (capacity >= 0xffffffffffffffffULL * load) - return ((void *)0); - if (!f_val) - return ((void *)0); - size_t real_capacity = hms_impl_calculate_size(capacity / load); - if (!alloc) - alloc = &cmc_alloc_node_default; - struct hashmultiset *_set_ = alloc->malloc(sizeof(struct hashmultiset)); - if (!_set_) - return ((void *)0); - _set_->buffer = alloc->calloc(real_capacity, sizeof(struct hashmultiset_entry)); - if (!_set_->buffer) - { - alloc->free(_set_); - return ((void *)0); - } - _set_->count = 0; - _set_->cardinality = 0; - _set_->capacity = real_capacity; - _set_->load = load; - _set_->flag = CMC_FLAG_OK; - _set_->f_val = f_val; - _set_->alloc = alloc; - (_set_)->callbacks = callbacks; - return _set_; -} -void hms_clear(struct hashmultiset *_set_) -{ - if (_set_->f_val->free) - { - for (size_t i = 0; i < _set_->capacity; i++) - { - struct hashmultiset_entry *entry = &(_set_->buffer[i]); - if (entry->state == CMC_ES_FILLED) - { - _set_->f_val->free(entry->value); - } - } - } - memset(_set_->buffer, 0, sizeof(struct hashmultiset_entry) * _set_->capacity); - _set_->count = 0; - _set_->flag = CMC_FLAG_OK; -} -void hms_free(struct hashmultiset *_set_) -{ - if (_set_->f_val->free) - { - for (size_t i = 0; i < _set_->capacity; i++) - { - struct hashmultiset_entry *entry = &(_set_->buffer[i]); - if (entry->state == CMC_ES_FILLED) - { - _set_->f_val->free(entry->value); - } - } - } - _set_->alloc->free(_set_->buffer); - _set_->alloc->free(_set_); -} -void hms_customize(struct hashmultiset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (!alloc) - _set_->alloc = &cmc_alloc_node_default; - else - _set_->alloc = alloc; - (_set_)->callbacks = callbacks; - _set_->flag = CMC_FLAG_OK; -} -_Bool hms_insert(struct hashmultiset *_set_, size_t value) -{ - _Bool new_node; - struct hashmultiset_entry *entry = hms_impl_insert_and_return(_set_, value, &new_node); - if (!entry) - { - _set_->flag = CMC_FLAG_ERROR; - return 0; - } - if (!new_node) - entry->multiplicity++; - _set_->cardinality++; - _set_->flag = CMC_FLAG_OK; - if ((_set_)->callbacks && (_set_)->callbacks->create) - (_set_)->callbacks->create(); - ; - return 1; -} -_Bool hms_insert_many(struct hashmultiset *_set_, size_t value, size_t count) -{ - if (count == 0) - goto success; - _Bool new_node; - struct hashmultiset_entry *entry = hms_impl_insert_and_return(_set_, value, &new_node); - if (!entry) - { - _set_->flag = CMC_FLAG_ERROR; - return 0; - } - if (new_node) - entry->multiplicity = count; - else - entry->multiplicity += count; - _set_->cardinality += count; -success: - _set_->flag = CMC_FLAG_OK; - if ((_set_)->callbacks && (_set_)->callbacks->create) - (_set_)->callbacks->create(); - ; - return 1; -} -_Bool hms_update(struct hashmultiset *_set_, size_t value, size_t multiplicity) -{ - if (multiplicity == 0) - { - struct hashmultiset_entry *result = hms_impl_get_entry(_set_, value); - if (!result) - goto success; - _set_->count--; - _set_->cardinality -= result->multiplicity; - result->value = (size_t){ 0 }; - result->multiplicity = 0; - result->dist = 0; - result->state = CMC_ES_DELETED; - goto success; - } - _Bool new_node; - struct hashmultiset_entry *entry = hms_impl_insert_and_return(_set_, value, &new_node); - if (!entry) - return 0; - if (new_node) - _set_->cardinality++; - _set_->cardinality = (_set_->cardinality - entry->multiplicity) + multiplicity; - entry->multiplicity = multiplicity; -success: - _set_->flag = CMC_FLAG_OK; - if ((_set_)->callbacks && (_set_)->callbacks->update) - (_set_)->callbacks->update(); - ; - return 1; -} -_Bool hms_remove(struct hashmultiset *_set_, size_t value) -{ - if (hms_empty(_set_)) - { - _set_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct hashmultiset_entry *result = hms_impl_get_entry(_set_, value); - if (!result) - { - _set_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - if (result->multiplicity > 1) - result->multiplicity--; - else - { - result->value = (size_t){ 0 }; - result->multiplicity = 0; - result->dist = 0; - result->state = CMC_ES_DELETED; - _set_->count--; - } - _set_->cardinality--; - _set_->flag = CMC_FLAG_OK; - if ((_set_)->callbacks && (_set_)->callbacks->delete) - (_set_)->callbacks->delete (); - ; - return 1; -} -size_t hms_remove_all(struct hashmultiset *_set_, size_t value) -{ - if (hms_empty(_set_)) - { - _set_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct hashmultiset_entry *result = hms_impl_get_entry(_set_, value); - if (!result) - { - _set_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - size_t removed = result->multiplicity; - result->value = (size_t){ 0 }; - result->multiplicity = 0; - result->dist = 0; - result->state = CMC_ES_DELETED; - _set_->count--; - _set_->cardinality -= removed; - _set_->flag = CMC_FLAG_OK; - if ((_set_)->callbacks && (_set_)->callbacks->delete) - (_set_)->callbacks->delete (); - ; - return removed; -} -_Bool hms_max(struct hashmultiset *_set_, size_t *value) -{ - if (hms_empty(_set_)) - { - _set_->flag = CMC_FLAG_EMPTY; - return 0; - } - _Bool first = 1; - size_t max_val = (size_t){ 0 }; - for (size_t i = 0; i < _set_->capacity; i++) - { - if (_set_->buffer[i].state == CMC_ES_FILLED) - { - if (first) - { - max_val = _set_->buffer[i].value; - first = 0; - } - else if (_set_->f_val->cmp(_set_->buffer[i].value, max_val) > 0) - { - max_val = _set_->buffer[i].value; - } - } - } - if (value) - *value = max_val; - _set_->flag = CMC_FLAG_OK; - if ((_set_)->callbacks && (_set_)->callbacks->read) - (_set_)->callbacks->read(); - ; - return 1; -} -_Bool hms_min(struct hashmultiset *_set_, size_t *value) -{ - if (hms_empty(_set_)) - { - _set_->flag = CMC_FLAG_EMPTY; - return 0; - } - _Bool first = 1; - size_t min_val = (size_t){ 0 }; - for (size_t i = 0; i < _set_->capacity; i++) - { - if (_set_->buffer[i].state == CMC_ES_FILLED) - { - if (first) - { - min_val = _set_->buffer[i].value; - first = 0; - } - else if (_set_->f_val->cmp(_set_->buffer[i].value, min_val) < 0) - { - min_val = _set_->buffer[i].value; - } - } - } - if (value) - *value = min_val; - _set_->flag = CMC_FLAG_OK; - if ((_set_)->callbacks && (_set_)->callbacks->read) - (_set_)->callbacks->read(); - ; - return 1; -} -size_t hms_multiplicity_of(struct hashmultiset *_set_, size_t value) -{ - struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value); - _set_->flag = CMC_FLAG_OK; - if ((_set_)->callbacks && (_set_)->callbacks->read) - (_set_)->callbacks->read(); - ; - if (!entry) - return 0; - return entry->multiplicity; -} -_Bool hms_contains(struct hashmultiset *_set_, size_t value) -{ - _set_->flag = CMC_FLAG_OK; - _Bool result = hms_impl_get_entry(_set_, value) != ((void *)0); - if ((_set_)->callbacks && (_set_)->callbacks->read) - (_set_)->callbacks->read(); - ; - return result; -} -_Bool hms_empty(struct hashmultiset *_set_) -{ - return _set_->count == 0; -} -_Bool hms_full(struct hashmultiset *_set_) -{ - return (double)_set_->capacity * _set_->load <= (double)_set_->count; -} -size_t hms_count(struct hashmultiset *_set_) -{ - return _set_->count; -} -size_t hms_cardinality(struct hashmultiset *_set_) -{ - return _set_->cardinality; -} -size_t hms_capacity(struct hashmultiset *_set_) -{ - return _set_->capacity; -} -double hms_load(struct hashmultiset *_set_) -{ - return _set_->load; -} -int hms_flag(struct hashmultiset *_set_) -{ - return _set_->flag; -} -_Bool hms_resize(struct hashmultiset *_set_, size_t capacity) -{ - _set_->flag = CMC_FLAG_OK; - if (_set_->capacity == capacity) - goto success; - if (_set_->capacity > capacity / _set_->load) - goto success; - if (capacity >= 0xffffffffffffffffULL * _set_->load) - { - _set_->flag = CMC_FLAG_ERROR; - return 0; - } - size_t theoretical_size = hms_impl_calculate_size(capacity); - if (theoretical_size < _set_->count / _set_->load) - { - _set_->flag = CMC_FLAG_INVALID; - return 0; - } - struct hashmultiset *_new_set_ = hms_new_custom(capacity, _set_->load, _set_->f_val, _set_->alloc, ((void *)0)); - if (!_new_set_) - { - _set_->flag = CMC_FLAG_ERROR; - return 0; - } - for (size_t i = 0; i < _set_->capacity; i++) - { - if (_set_->buffer[i].state == CMC_ES_FILLED) - { - size_t value = _set_->buffer[i].value; - size_t multiplicity = _set_->buffer[i].multiplicity; - struct hashmultiset_entry *entry = hms_impl_insert_and_return(_new_set_, value, ((void *)0)); - entry->multiplicity = multiplicity; - } - } - if (_set_->count != _new_set_->count) - { - hms_free(_new_set_); - _set_->flag = CMC_FLAG_ERROR; - return 0; - } - struct hashmultiset_entry *tmp_b = _set_->buffer; - _set_->buffer = _new_set_->buffer; - _new_set_->buffer = tmp_b; - size_t tmp_c = _set_->capacity; - _set_->capacity = _new_set_->capacity; - _new_set_->capacity = tmp_c; - _new_set_->f_val = &(struct hashmultiset_fval){ ((void *)0) }; - hms_free(_new_set_); -success: - if ((_set_)->callbacks && (_set_)->callbacks->resize) - (_set_)->callbacks->resize(); - ; - return 1; -} -struct hashmultiset *hms_copy_of(struct hashmultiset *_set_) -{ - struct hashmultiset *result = - hms_new_custom(_set_->capacity * _set_->load, _set_->load, _set_->f_val, _set_->alloc, ((void *)0)); - if (!result) - { - _set_->flag = CMC_FLAG_ERROR; - return ((void *)0); - } - (result)->callbacks = _set_->callbacks; - if (_set_->f_val->cpy) - { - for (size_t i = 0; i < _set_->capacity; i++) - { - struct hashmultiset_entry *scan = &(_set_->buffer[i]); - if (scan->state != CMC_ES_EMPTY) - { - struct hashmultiset_entry *target = &(result->buffer[i]); - if (scan->state == CMC_ES_DELETED) - target->state = CMC_ES_DELETED; - else - { - target->state = scan->state; - target->dist = scan->dist; - target->multiplicity = scan->multiplicity; - target->value = _set_->f_val->cpy(scan->value); - } - } - } - } - else - memcpy(result->buffer, _set_->buffer, sizeof(struct hashmultiset_entry) * _set_->capacity); - result->count = _set_->count; - result->cardinality = _set_->cardinality; - _set_->flag = CMC_FLAG_OK; - return result; -} -_Bool hms_equals(struct hashmultiset *_set1_, struct hashmultiset *_set2_) -{ - _set1_->flag = CMC_FLAG_OK; - _set2_->flag = CMC_FLAG_OK; - if (_set1_->count != _set2_->count) - return 0; - if (_set1_->cardinality != _set2_->cardinality) - return 0; - if (_set1_->count == 0) - return 1; - struct hashmultiset *_set_a_; - struct hashmultiset *_set_b_; - _set_a_ = _set1_->capacity < _set2_->capacity ? _set1_ : _set2_; - _set_b_ = _set_a_ == _set1_ ? _set2_ : _set1_; - for (size_t i = 0; i < _set_a_->capacity; i++) - { - if (_set_a_->buffer[i].state == CMC_ES_FILLED) - { - struct hashmultiset_entry *entry_a = &(_set_a_->buffer[i]); - struct hashmultiset_entry *entry_b = hms_impl_get_entry(_set_b_, entry_a->value); - if (!entry_b) - return 0; - if (entry_a->multiplicity != entry_b->multiplicity) - return 0; - } - } - return 1; -} -static size_t hms_impl_multiplicity_of(struct hashmultiset *_set_, size_t value) -{ - struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value); - if (!entry) - return 0; - return entry->multiplicity; -} -static struct hashmultiset_entry *hms_impl_insert_and_return(struct hashmultiset *_set_, size_t value, _Bool *new_node) -{ - if (new_node) - *new_node = 0; - struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value); - if (entry != ((void *)0)) - return entry; - if (new_node) - *new_node = 1; - if (hms_full(_set_)) - { - if (!hms_resize(_set_, _set_->capacity + 1)) - return ((void *)0); - } - size_t hash = _set_->f_val->hash(value); - size_t original_pos = hash % _set_->capacity; - size_t pos = original_pos; - size_t curr_mul = 1; - struct hashmultiset_entry *target = &(_set_->buffer[pos]); - struct hashmultiset_entry *to_return = ((void *)0); - if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) - { - target->value = value; - target->multiplicity = curr_mul; - target->dist = pos - original_pos; - target->state = CMC_ES_FILLED; - to_return = target; - } - else - { - while (1) - { - pos++; - target = &(_set_->buffer[pos % _set_->capacity]); - if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) - { - target->value = value; - target->multiplicity = curr_mul; - target->dist = pos - original_pos; - target->state = CMC_ES_FILLED; - if (!to_return) - to_return = target; - break; - } - else if (target->dist < pos - original_pos) - { - size_t tmp = target->value; - size_t tmp_dist = target->dist; - size_t tmp_mul = target->multiplicity; - target->value = value; - target->dist = pos - original_pos; - target->multiplicity = curr_mul; - value = tmp; - original_pos = pos - tmp_dist; - curr_mul = tmp_mul; - if (!to_return) - to_return = target; - } - } - } - _set_->count++; - return to_return; -} -static struct hashmultiset_entry *hms_impl_get_entry(struct hashmultiset *_set_, size_t value) -{ - size_t hash = _set_->f_val->hash(value); - size_t pos = hash % _set_->capacity; - struct hashmultiset_entry *target = &(_set_->buffer[pos]); - while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED) - { - if (_set_->f_val->cmp(target->value, value) == 0) - return target; - pos++; - target = &(_set_->buffer[pos % _set_->capacity]); - } - return ((void *)0); -} -static size_t hms_impl_calculate_size(size_t required) -{ - const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); - if (cmc_hashtable_primes[count - 1] < required) - return required; - size_t i = 0; - while (cmc_hashtable_primes[i] < required) - i++; - return cmc_hashtable_primes[i]; -} -struct hashmultiset_iter hms_iter_start(struct hashmultiset *target) -{ - struct hashmultiset_iter iter; - iter.target = target; - iter.cursor = 0; - iter.index = 0; - iter.first = 0; - iter.last = 0; - iter.start = 1; - iter.end = hms_empty(target); - if (!hms_empty(target)) - { - for (size_t i = 0; i < target->capacity; i++) - { - if (target->buffer[i].state == CMC_ES_FILLED) - { - iter.first = i; - break; - } - } - iter.cursor = iter.first; - for (size_t i = target->capacity; i > 0; i--) - { - if (target->buffer[i - 1].state == CMC_ES_FILLED) - { - iter.last = i - 1; - break; - } - } - } - return iter; -} -struct hashmultiset_iter hms_iter_end(struct hashmultiset *target) -{ - struct hashmultiset_iter iter; - iter.target = target; - iter.cursor = 0; - iter.index = 0; - iter.first = 0; - iter.last = 0; - iter.start = hms_empty(target); - iter.end = 1; - if (!hms_empty(target)) - { - for (size_t i = 0; i < target->capacity; i++) - { - if (target->buffer[i].state == CMC_ES_FILLED) - { - iter.first = i; - break; - } - } - for (size_t i = target->capacity; i > 0; i--) - { - if (target->buffer[i - 1].state == CMC_ES_FILLED) - { - iter.last = i - 1; - break; - } - } - iter.cursor = iter.last; - iter.index = target->count - 1; - } - return iter; -} -_Bool hms_iter_at_start(struct hashmultiset_iter *iter) -{ - return hms_empty(iter->target) || iter->start; -} -_Bool hms_iter_at_end(struct hashmultiset_iter *iter) -{ - return hms_empty(iter->target) || iter->end; -} -_Bool hms_iter_to_start(struct hashmultiset_iter *iter) -{ - if (!hms_empty(iter->target)) - { - iter->cursor = iter->first; - iter->index = 0; - iter->start = 1; - iter->end = hms_empty(iter->target); - return 1; - } - return 0; -} -_Bool hms_iter_to_end(struct hashmultiset_iter *iter) -{ - if (!hms_empty(iter->target)) - { - iter->cursor = iter->last; - iter->index = iter->target->count - 1; - iter->start = hms_empty(iter->target); - iter->end = 1; - return 1; - } - return 0; -} -_Bool hms_iter_next(struct hashmultiset_iter *iter) -{ - if (iter->end) - return 0; - if (iter->index + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - iter->start = hms_empty(iter->target); - struct hashmultiset_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 1; -} -_Bool hms_iter_prev(struct hashmultiset_iter *iter) -{ - if (iter->start) - return 0; - if (iter->index == 0) - { - iter->start = 1; - return 0; - } - iter->end = hms_empty(iter->target); - struct hashmultiset_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 1; -} -_Bool hms_iter_advance(struct hashmultiset_iter *iter, size_t steps) -{ - if (iter->end) - return 0; - if (iter->index + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - if (steps == 0 || iter->index + steps >= iter->target->count) - return 0; - for (size_t i = 0; i < steps; i++) - hms_iter_next(iter); - return 1; -} -_Bool hms_iter_rewind(struct hashmultiset_iter *iter, size_t steps) -{ - if (iter->start) - return 0; - if (iter->index == 0) - { - iter->start = 1; - return 0; - } - if (steps == 0 || iter->index < steps) - return 0; - for (size_t i = 0; i < steps; i++) - hms_iter_prev(iter); - return 1; -} -_Bool hms_iter_go_to(struct hashmultiset_iter *iter, size_t index) -{ - if (index >= iter->target->count) - return 0; - if (iter->index > index) - return hms_iter_rewind(iter, iter->index - index); - else if (iter->index < index) - return hms_iter_advance(iter, index - iter->index); - return 1; -} -size_t hms_iter_value(struct hashmultiset_iter *iter) -{ - if (hms_empty(iter->target)) - return (size_t){ 0 }; - return iter->target->buffer[iter->cursor].value; -} -size_t hms_iter_multiplicity(struct hashmultiset_iter *iter) -{ - if (hms_empty(iter->target)) - return 0; - return iter->target->buffer[iter->cursor].multiplicity; -} -size_t hms_iter_index(struct hashmultiset_iter *iter) -{ - return iter->index; -} -struct hashmultiset *hms_union(struct hashmultiset *_set1_, struct hashmultiset *_set2_) -{ - struct hashmultiset *_set_r_ = - hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - return ((void *)0); - struct hashmultiset_iter iter1 = hms_iter_start(_set1_); - struct hashmultiset_iter iter2 = hms_iter_start(_set2_); - for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1)) - { - size_t value = hms_iter_value(&iter1); - size_t m1 = hms_iter_multiplicity(&iter1); - size_t m2 = hms_impl_multiplicity_of(_set2_, value); - size_t max_ = m1 > m2 ? m1 : m2; - hms_update(_set_r_, value, max_); - } - for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2)) - { - size_t value = hms_iter_value(&iter2); - size_t m1 = hms_impl_multiplicity_of(_set1_, value); - size_t m2 = hms_iter_multiplicity(&iter2); - size_t max_ = m1 > m2 ? m1 : m2; - hms_update(_set_r_, value, max_); - } - (_set_r_)->callbacks = _set1_->callbacks; - return _set_r_; -} -struct hashmultiset *hms_intersection(struct hashmultiset *_set1_, struct hashmultiset *_set2_) -{ - struct hashmultiset *_set_r_ = - hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - return ((void *)0); - struct hashmultiset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; - struct hashmultiset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; - struct hashmultiset_iter iter = hms_iter_start(_set_A_); - for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) - { - size_t value = hms_iter_value(&iter); - size_t m1 = hms_iter_multiplicity(&iter); - size_t m2 = hms_impl_multiplicity_of(_set_B_, value); - size_t max_ = m1 < m2 ? m1 : m2; - hms_update(_set_r_, value, max_); - } - (_set_r_)->callbacks = _set1_->callbacks; - return _set_r_; -} -struct hashmultiset *hms_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_) -{ - struct hashmultiset *_set_r_ = - hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - return ((void *)0); - struct hashmultiset_iter iter = hms_iter_start(_set1_); - for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) - { - size_t value = hms_iter_value(&iter); - size_t m1 = hms_iter_multiplicity(&iter); - size_t m2 = hms_impl_multiplicity_of(_set2_, value); - if (m1 > m2) - hms_update(_set_r_, value, m1 - m2); - } - (_set_r_)->callbacks = _set1_->callbacks; - return _set_r_; -} -struct hashmultiset *hms_summation(struct hashmultiset *_set1_, struct hashmultiset *_set2_) -{ - struct hashmultiset *_set_r_ = - hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - return ((void *)0); - struct hashmultiset_iter iter1 = hms_iter_start(_set1_); - struct hashmultiset_iter iter2 = hms_iter_start(_set2_); - for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1)) - { - hms_insert_many(_set_r_, hms_iter_value(&iter1), hms_iter_multiplicity(&iter1)); - } - for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2)) - { - hms_insert_many(_set_r_, hms_iter_value(&iter2), hms_iter_multiplicity(&iter2)); - } - (_set_r_)->callbacks = _set1_->callbacks; - return _set_r_; -} -struct hashmultiset *hms_symmetric_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_) -{ - struct hashmultiset *_set_r_ = - hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - return ((void *)0); - struct hashmultiset_iter iter1 = hms_iter_start(_set1_); - struct hashmultiset_iter iter2 = hms_iter_start(_set2_); - for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1)) - { - size_t value = hms_iter_value(&iter1); - size_t m1 = hms_iter_multiplicity(&iter1); - size_t m2 = hms_impl_multiplicity_of(_set2_, value); - if (m1 != m2) - { - if (m1 > m2) - hms_update(_set_r_, value, m1 - m2); - else - hms_update(_set_r_, value, m2 - m1); - } - } - for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2)) - { - size_t value = hms_iter_value(&iter2); - size_t m1 = hms_impl_multiplicity_of(_set1_, value); - size_t m2 = hms_iter_multiplicity(&iter2); - if (m1 != m2) - { - if (m1 > m2) - hms_update(_set_r_, value, m1 - m2); - else - hms_update(_set_r_, value, m2 - m1); - } - } - (_set_r_)->callbacks = _set1_->callbacks; - return _set_r_; -} -_Bool hms_is_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) -{ - if (_set1_->count > _set2_->count) - return 0; - if (hms_empty(_set1_)) - return 1; - struct hashmultiset_iter iter = hms_iter_start(_set1_); - for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) - { - size_t value = hms_iter_value(&iter); - size_t m1 = hms_iter_multiplicity(&iter); - size_t m2 = hms_impl_multiplicity_of(_set2_, value); - if (m1 > m2) - return 0; - } - return 1; -} -_Bool hms_is_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) -{ - return hms_is_subset(_set2_, _set1_); -} -_Bool hms_is_proper_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) -{ - if (_set1_->count >= _set2_->count) - return 0; - if (hms_empty(_set1_)) - { - if (!hms_empty(_set2_)) - return 1; - else - return 0; - } - struct hashmultiset_iter iter = hms_iter_start(_set1_); - for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) - { - size_t value = hms_iter_value(&iter); - size_t m1 = hms_iter_multiplicity(&iter); - size_t m2 = hms_impl_multiplicity_of(_set2_, value); - if (m1 >= m2) - return 0; - } - return 1; -} -_Bool hms_is_proper_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) -{ - return hms_is_proper_subset(_set2_, _set1_); -} -_Bool hms_is_disjointset(struct hashmultiset *_set1_, struct hashmultiset *_set2_) -{ - if (hms_empty(_set1_)) - return 1; - struct hashmultiset_iter iter = hms_iter_start(_set1_); - for (; !hms_iter_at_end(&iter); hms_iter_next(&iter)) - { - size_t value = hms_iter_value(&iter); - if (hms_impl_get_entry(_set2_, value) != ((void *)0)) - return 0; - } - return 1; -} -_Bool hms_to_string(struct hashmultiset *_set_, FILE *fptr) -{ - struct hashmultiset *s_ = _set_; - return 0 <= fprintf(fptr, - "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" - "I64u" - ", " - "count:%" - "I64u" - ", " - "cardinality:%" - "I64u" - ", " - "load:%lf, " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }", - "hashmultiset", "size_t", s_, s_->buffer, s_->capacity, s_->count, s_->cardinality, s_->load, - s_->flag, s_->f_val, s_->alloc, (s_)->callbacks); -} -_Bool hms_print(struct hashmultiset *_set_, FILE *fptr, const char *start, const char *separator, const char *end, - const char *val_mul_sep) -{ - fprintf(fptr, "%s", start); - size_t last = 0; - for (size_t i = _set_->capacity; i > 0; i--) - { - if ((_set_->buffer[i - 1]).state == CMC_ES_FILLED) - { - last = i - 1; - break; - } - } - for (size_t i = 0; i < _set_->capacity; i++) - { - struct hashmultiset_entry *entry = &(_set_->buffer[i]); - if (entry->state == CMC_ES_FILLED) - { - if (!_set_->f_val->str(fptr, entry->value)) - return 0; - fprintf(fptr, "%s", val_mul_sep); - if (fprintf(fptr, - "%" - "I64u" - "", - entry->multiplicity) < 0) - return 0; - if (i + 1 < last) - fprintf(fptr, "%s", separator); - } - } - fprintf(fptr, "%s", end); - return 1; -} diff --git a/tests/src/tst_cmc_hashset.c b/tests/src/tst_cmc_hashset.c deleted file mode 100644 index 1e4764b..0000000 --- a/tests/src/tst_cmc_hashset.c +++ /dev/null @@ -1,773 +0,0 @@ - -#include "tst_cmc_hashset.h" - -static struct hashset_entry *hs_impl_get_entry(struct hashset *_set_, size_t value); -static size_t hs_impl_calculate_size(size_t required); -struct hashset *hs_new(size_t capacity, double load, struct hashset_fval *f_val) -{ - return hs_new_custom(capacity, load, f_val, ((void *)0), ((void *)0)); -} -struct hashset *hs_new_custom(size_t capacity, double load, struct hashset_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) -{ - ; - if (capacity == 0 || load <= 0 || load >= 1) - return ((void *)0); - if (capacity >= 0xffffffffffffffffULL * load) - return ((void *)0); - if (!f_val) - return ((void *)0); - size_t real_capacity = hs_impl_calculate_size(capacity / load); - if (!alloc) - alloc = &cmc_alloc_node_default; - struct hashset *_set_ = alloc->malloc(sizeof(struct hashset)); - if (!_set_) - return ((void *)0); - _set_->buffer = alloc->calloc(real_capacity, sizeof(struct hashset_entry)); - if (!_set_->buffer) - { - alloc->free(_set_); - return ((void *)0); - } - _set_->count = 0; - _set_->capacity = real_capacity; - _set_->load = load; - _set_->flag = CMC_FLAG_OK; - _set_->f_val = f_val; - _set_->alloc = alloc; - (_set_)->callbacks = callbacks; - return _set_; -} -void hs_clear(struct hashset *_set_) -{ - if (_set_->f_val->free) - { - for (size_t i = 0; i < _set_->capacity; i++) - { - struct hashset_entry *entry = &(_set_->buffer[i]); - if (entry->state == CMC_ES_FILLED) - { - _set_->f_val->free(entry->value); - } - } - } - memset(_set_->buffer, 0, sizeof(struct hashset_entry) * _set_->capacity); - _set_->count = 0; - _set_->flag = CMC_FLAG_OK; -} -void hs_free(struct hashset *_set_) -{ - if (_set_->f_val->free) - { - for (size_t i = 0; i < _set_->capacity; i++) - { - struct hashset_entry *entry = &(_set_->buffer[i]); - if (entry->state == CMC_ES_FILLED) - { - _set_->f_val->free(entry->value); - } - } - } - _set_->alloc->free(_set_->buffer); - _set_->alloc->free(_set_); -} -void hs_customize(struct hashset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (!alloc) - _set_->alloc = &cmc_alloc_node_default; - else - _set_->alloc = alloc; - (_set_)->callbacks = callbacks; - _set_->flag = CMC_FLAG_OK; -} -_Bool hs_insert(struct hashset *_set_, size_t value) -{ - if (hs_full(_set_)) - { - if (!hs_resize(_set_, _set_->capacity + 1)) - return 0; - } - if (hs_impl_get_entry(_set_, value) != ((void *)0)) - { - _set_->flag = CMC_FLAG_DUPLICATE; - return 0; - } - size_t hash = _set_->f_val->hash(value); - size_t original_pos = hash % _set_->capacity; - size_t pos = original_pos; - struct hashset_entry *target = &(_set_->buffer[pos]); - if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) - { - target->value = value; - target->dist = 0; - target->state = CMC_ES_FILLED; - } - else - { - while (1) - { - pos++; - target = &(_set_->buffer[pos % _set_->capacity]); - if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) - { - target->value = value; - target->dist = pos - original_pos; - target->state = CMC_ES_FILLED; - break; - } - else if (target->dist < pos - original_pos) - { - size_t tmp = target->value; - size_t tmp_dist = target->dist; - target->value = value; - target->dist = pos - original_pos; - value = tmp; - original_pos = pos - tmp_dist; - } - } - } - _set_->count++; - _set_->flag = CMC_FLAG_OK; - if ((_set_)->callbacks && (_set_)->callbacks->create) - (_set_)->callbacks->create(); - ; - return 1; -} -_Bool hs_remove(struct hashset *_set_, size_t value) -{ - if (hs_empty(_set_)) - { - _set_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct hashset_entry *result = hs_impl_get_entry(_set_, value); - if (result == ((void *)0)) - { - _set_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - result->value = (size_t){ 0 }; - result->dist = 0; - result->state = CMC_ES_DELETED; - _set_->count--; - _set_->flag = CMC_FLAG_OK; - if ((_set_)->callbacks && (_set_)->callbacks->delete) - (_set_)->callbacks->delete (); - ; - return 1; -} -_Bool hs_max(struct hashset *_set_, size_t *value) -{ - if (hs_empty(_set_)) - { - _set_->flag = CMC_FLAG_EMPTY; - return 0; - } - _Bool first = 1; - size_t max_val = (size_t){ 0 }; - for (size_t i = 0; i < _set_->capacity; i++) - { - if (_set_->buffer[i].state == CMC_ES_FILLED) - { - if (first) - { - max_val = _set_->buffer[i].value; - first = 0; - } - else if (_set_->f_val->cmp(_set_->buffer[i].value, max_val) > 0) - { - max_val = _set_->buffer[i].value; - } - } - } - if (value) - *value = max_val; - _set_->flag = CMC_FLAG_OK; - if ((_set_)->callbacks && (_set_)->callbacks->read) - (_set_)->callbacks->read(); - ; - return 1; -} -_Bool hs_min(struct hashset *_set_, size_t *value) -{ - if (hs_empty(_set_)) - { - _set_->flag = CMC_FLAG_EMPTY; - return 0; - } - _Bool first = 1; - size_t min_val = (size_t){ 0 }; - for (size_t i = 0; i < _set_->capacity; i++) - { - if (_set_->buffer[i].state == CMC_ES_FILLED) - { - if (first) - { - min_val = _set_->buffer[i].value; - first = 0; - } - else if (_set_->f_val->cmp(_set_->buffer[i].value, min_val) < 0) - { - min_val = _set_->buffer[i].value; - } - } - } - if (value) - *value = min_val; - _set_->flag = CMC_FLAG_OK; - if ((_set_)->callbacks && (_set_)->callbacks->read) - (_set_)->callbacks->read(); - ; - return 1; -} -_Bool hs_contains(struct hashset *_set_, size_t value) -{ - _set_->flag = CMC_FLAG_OK; - _Bool result = hs_impl_get_entry(_set_, value) != ((void *)0); - if ((_set_)->callbacks && (_set_)->callbacks->read) - (_set_)->callbacks->read(); - ; - return result; -} -_Bool hs_empty(struct hashset *_set_) -{ - return _set_->count == 0; -} -_Bool hs_full(struct hashset *_set_) -{ - return (double)_set_->capacity * _set_->load <= (double)_set_->count; -} -size_t hs_count(struct hashset *_set_) -{ - return _set_->count; -} -size_t hs_capacity(struct hashset *_set_) -{ - return _set_->capacity; -} -double hs_load(struct hashset *_set_) -{ - return _set_->load; -} -int hs_flag(struct hashset *_set_) -{ - return _set_->flag; -} -_Bool hs_resize(struct hashset *_set_, size_t capacity) -{ - _set_->flag = CMC_FLAG_OK; - if (_set_->capacity == capacity) - goto success; - if (_set_->capacity > capacity / _set_->load) - goto success; - if (capacity >= 0xffffffffffffffffULL * _set_->load) - { - _set_->flag = CMC_FLAG_ERROR; - return 0; - } - size_t theoretical_size = hs_impl_calculate_size(capacity); - if (theoretical_size < _set_->count / _set_->load) - { - _set_->flag = CMC_FLAG_INVALID; - return 0; - } - struct hashset *_new_set_ = hs_new_custom(capacity, _set_->load, _set_->f_val, _set_->alloc, ((void *)0)); - if (!_new_set_) - { - _set_->flag = CMC_FLAG_ALLOC; - return 0; - } - for (size_t i = 0; i < _set_->capacity; i++) - { - if (_set_->buffer[i].state == CMC_ES_FILLED) - { - size_t value = _set_->buffer[i].value; - hs_insert(_new_set_, value); - } - } - if (_set_->count != _new_set_->count) - { - hs_free(_new_set_); - _set_->flag = CMC_FLAG_ERROR; - return 0; - } - struct hashset_entry *tmp_b = _set_->buffer; - _set_->buffer = _new_set_->buffer; - _new_set_->buffer = tmp_b; - size_t tmp_c = _set_->capacity; - _set_->capacity = _new_set_->capacity; - _new_set_->capacity = tmp_c; - _new_set_->f_val = &(struct hashset_fval){ ((void *)0) }; - hs_free(_new_set_); -success: - if ((_set_)->callbacks && (_set_)->callbacks->resize) - (_set_)->callbacks->resize(); - ; - return 1; -} -struct hashset *hs_copy_of(struct hashset *_set_) -{ - struct hashset *result = - hs_new_custom(_set_->capacity * _set_->load, _set_->load, _set_->f_val, _set_->alloc, ((void *)0)); - if (!result) - { - _set_->flag = CMC_FLAG_ERROR; - return ((void *)0); - } - (result)->callbacks = _set_->callbacks; - if (_set_->f_val->cpy) - { - for (size_t i = 0; i < _set_->capacity; i++) - { - struct hashset_entry *scan = &(_set_->buffer[i]); - if (scan->state != CMC_ES_EMPTY) - { - struct hashset_entry *target = &(result->buffer[i]); - if (scan->state == CMC_ES_DELETED) - target->state = CMC_ES_DELETED; - else - { - target->state = scan->state; - target->dist = scan->dist; - target->value = _set_->f_val->cpy(scan->value); - } - } - } - } - else - memcpy(result->buffer, _set_->buffer, sizeof(struct hashset_entry) * _set_->capacity); - result->count = _set_->count; - _set_->flag = CMC_FLAG_OK; - return result; -} -_Bool hs_equals(struct hashset *_set1_, struct hashset *_set2_) -{ - _set1_->flag = CMC_FLAG_OK; - _set2_->flag = CMC_FLAG_OK; - if (_set1_->count != _set2_->count) - return 0; - struct hashset *_set_a_; - struct hashset *_set_b_; - _set_a_ = _set1_->capacity < _set2_->capacity ? _set1_ : _set2_; - _set_b_ = _set_a_ == _set1_ ? _set2_ : _set1_; - for (size_t i = 0; i < _set_a_->capacity; i++) - { - if (_set_a_->buffer[i].state == CMC_ES_FILLED) - { - if (!hs_impl_get_entry(_set_b_, _set_a_->buffer[i].value)) - return 0; - } - } - return 1; -} -static struct hashset_entry *hs_impl_get_entry(struct hashset *_set_, size_t value) -{ - size_t hash = _set_->f_val->hash(value); - size_t pos = hash % _set_->capacity; - struct hashset_entry *target = &(_set_->buffer[pos]); - while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED) - { - if (_set_->f_val->cmp(target->value, value) == 0) - return target; - pos++; - target = &(_set_->buffer[pos % _set_->capacity]); - } - return ((void *)0); -} -static size_t hs_impl_calculate_size(size_t required) -{ - const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); - if (cmc_hashtable_primes[count - 1] < required) - return required; - size_t i = 0; - while (cmc_hashtable_primes[i] < required) - i++; - return cmc_hashtable_primes[i]; -} -struct hashset_iter hs_iter_start(struct hashset *target) -{ - struct hashset_iter iter; - iter.target = target; - iter.cursor = 0; - iter.index = 0; - iter.first = 0; - iter.last = 0; - iter.start = 1; - iter.end = hs_empty(target); - if (!hs_empty(target)) - { - for (size_t i = 0; i < target->capacity; i++) - { - if (target->buffer[i].state == CMC_ES_FILLED) - { - iter.first = i; - break; - } - } - iter.cursor = iter.first; - for (size_t i = target->capacity; i > 0; i--) - { - if (target->buffer[i - 1].state == CMC_ES_FILLED) - { - iter.last = i - 1; - break; - } - } - } - return iter; -} -struct hashset_iter hs_iter_end(struct hashset *target) -{ - struct hashset_iter iter; - iter.target = target; - iter.cursor = 0; - iter.index = 0; - iter.first = 0; - iter.last = 0; - iter.start = hs_empty(target); - iter.end = 1; - if (!hs_empty(target)) - { - for (size_t i = 0; i < target->capacity; i++) - { - if (target->buffer[i].state == CMC_ES_FILLED) - { - iter.first = i; - break; - } - } - for (size_t i = target->capacity; i > 0; i--) - { - if (target->buffer[i - 1].state == CMC_ES_FILLED) - { - iter.last = i - 1; - break; - } - } - iter.cursor = iter.last; - iter.index = target->count - 1; - } - return iter; -} -_Bool hs_iter_at_start(struct hashset_iter *iter) -{ - return hs_empty(iter->target) || iter->start; -} -_Bool hs_iter_at_end(struct hashset_iter *iter) -{ - return hs_empty(iter->target) || iter->end; -} -_Bool hs_iter_to_start(struct hashset_iter *iter) -{ - if (!hs_empty(iter->target)) - { - iter->cursor = iter->first; - iter->index = 0; - iter->start = 1; - iter->end = hs_empty(iter->target); - return 1; - } - return 0; -} -_Bool hs_iter_to_end(struct hashset_iter *iter) -{ - if (!hs_empty(iter->target)) - { - iter->cursor = iter->last; - iter->index = iter->target->count - 1; - iter->start = hs_empty(iter->target); - iter->end = 1; - return 1; - } - return 0; -} -_Bool hs_iter_next(struct hashset_iter *iter) -{ - if (iter->end) - return 0; - if (iter->index + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - iter->start = hs_empty(iter->target); - struct hashset_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 1; -} -_Bool hs_iter_prev(struct hashset_iter *iter) -{ - if (iter->start) - return 0; - if (iter->index == 0) - { - iter->start = 1; - return 0; - } - iter->end = hs_empty(iter->target); - struct hashset_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 1; -} -_Bool hs_iter_advance(struct hashset_iter *iter, size_t steps) -{ - if (iter->end) - return 0; - if (iter->index + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - if (steps == 0 || iter->index + steps >= iter->target->count) - return 0; - for (size_t i = 0; i < steps; i++) - hs_iter_next(iter); - return 1; -} -_Bool hs_iter_rewind(struct hashset_iter *iter, size_t steps) -{ - if (iter->start) - return 0; - if (iter->index == 0) - { - iter->start = 1; - return 0; - } - if (steps == 0 || iter->index < steps) - return 0; - for (size_t i = 0; i < steps; i++) - hs_iter_prev(iter); - return 1; -} -_Bool hs_iter_go_to(struct hashset_iter *iter, size_t index) -{ - if (index >= iter->target->count) - return 0; - if (iter->index > index) - return hs_iter_rewind(iter, iter->index - index); - else if (iter->index < index) - return hs_iter_advance(iter, index - iter->index); - return 1; -} -size_t hs_iter_value(struct hashset_iter *iter) -{ - if (hs_empty(iter->target)) - return (size_t){ 0 }; - return iter->target->buffer[iter->cursor].value; -} -size_t hs_iter_index(struct hashset_iter *iter) -{ - return iter->index; -} -struct hashset *hs_union(struct hashset *_set1_, struct hashset *_set2_) -{ - struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - { - _set1_->flag = CMC_FLAG_ALLOC; - _set2_->flag = CMC_FLAG_ALLOC; - return ((void *)0); - } - struct hashset_iter iter1 = hs_iter_start(_set1_); - struct hashset_iter iter2 = hs_iter_start(_set2_); - for (; !hs_iter_at_end(&iter1); hs_iter_next(&iter1)) - { - hs_insert(_set_r_, hs_iter_value(&iter1)); - } - for (; !hs_iter_at_end(&iter2); hs_iter_next(&iter2)) - { - hs_insert(_set_r_, hs_iter_value(&iter2)); - } - (_set_r_)->callbacks = _set1_->callbacks; - return _set_r_; -} -struct hashset *hs_intersection(struct hashset *_set1_, struct hashset *_set2_) -{ - struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - { - _set1_->flag = CMC_FLAG_ALLOC; - _set2_->flag = CMC_FLAG_ALLOC; - return ((void *)0); - } - struct hashset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; - struct hashset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; - struct hashset_iter iter = hs_iter_start(_set_A_); - for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) - { - size_t value = hs_iter_value(&iter); - if (hs_impl_get_entry(_set_B_, value) != ((void *)0)) - hs_insert(_set_r_, value); - } - (_set_r_)->callbacks = _set1_->callbacks; - return _set_r_; -} -struct hashset *hs_difference(struct hashset *_set1_, struct hashset *_set2_) -{ - struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - { - _set1_->flag = CMC_FLAG_ALLOC; - _set2_->flag = CMC_FLAG_ALLOC; - return ((void *)0); - } - struct hashset_iter iter = hs_iter_start(_set1_); - for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) - { - size_t value = hs_iter_value(&iter); - if (hs_impl_get_entry(_set2_, value) == ((void *)0)) - hs_insert(_set_r_, value); - } - (_set_r_)->callbacks = _set1_->callbacks; - return _set_r_; -} -struct hashset *hs_symmetric_difference(struct hashset *_set1_, struct hashset *_set2_) -{ - struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - { - _set1_->flag = CMC_FLAG_ALLOC; - _set2_->flag = CMC_FLAG_ALLOC; - return ((void *)0); - } - struct hashset_iter iter1 = hs_iter_start(_set1_); - struct hashset_iter iter2 = hs_iter_start(_set2_); - for (; !hs_iter_at_end(&iter1); hs_iter_next(&iter1)) - { - size_t value = hs_iter_value(&iter1); - if (hs_impl_get_entry(_set2_, value) == ((void *)0)) - hs_insert(_set_r_, value); - } - for (; !hs_iter_at_end(&iter2); hs_iter_next(&iter2)) - { - size_t value = hs_iter_value(&iter2); - if (hs_impl_get_entry(_set1_, value) == ((void *)0)) - hs_insert(_set_r_, value); - } - (_set_r_)->callbacks = _set1_->callbacks; - return _set_r_; -} -_Bool hs_is_subset(struct hashset *_set1_, struct hashset *_set2_) -{ - _set1_->flag = CMC_FLAG_OK; - _set2_->flag = CMC_FLAG_OK; - if (_set1_->count > _set2_->count) - return 0; - if (hs_empty(_set1_)) - return 1; - struct hashset_iter iter = hs_iter_start(_set1_); - for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) - { - size_t value = hs_iter_value(&iter); - if (hs_impl_get_entry(_set2_, value) == ((void *)0)) - return 0; - } - return 1; -} -_Bool hs_is_superset(struct hashset *_set1_, struct hashset *_set2_) -{ - return hs_is_subset(_set2_, _set1_); -} -_Bool hs_is_proper_subset(struct hashset *_set1_, struct hashset *_set2_) -{ - _set1_->flag = CMC_FLAG_OK; - _set2_->flag = CMC_FLAG_OK; - if (_set1_->count >= _set2_->count) - return 0; - if (hs_empty(_set1_)) - { - if (!hs_empty(_set2_)) - return 1; - else - return 0; - } - struct hashset_iter iter = hs_iter_start(_set1_); - for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) - { - size_t value = hs_iter_value(&iter); - if (hs_impl_get_entry(_set2_, value) == ((void *)0)) - return 0; - } - return 1; -} -_Bool hs_is_proper_superset(struct hashset *_set1_, struct hashset *_set2_) -{ - return hs_is_proper_subset(_set2_, _set1_); -} -_Bool hs_is_disjointset(struct hashset *_set1_, struct hashset *_set2_) -{ - _set1_->flag = CMC_FLAG_OK; - _set2_->flag = CMC_FLAG_OK; - if (hs_empty(_set1_)) - return 1; - struct hashset_iter iter = hs_iter_start(_set1_); - for (; !hs_iter_at_end(&iter); hs_iter_next(&iter)) - { - size_t value = hs_iter_value(&iter); - if (hs_impl_get_entry(_set2_, value) != ((void *)0)) - return 0; - } - return 1; -} -_Bool hs_to_string(struct hashset *_set_, FILE *fptr) -{ - struct hashset *s_ = _set_; - return 0 <= fprintf(fptr, - "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" - "I64u" - ", " - "count:%" - "I64u" - ", " - "load:%lf, " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks: %p }", - "hashset", "size_t", s_, s_->buffer, s_->capacity, s_->count, s_->load, s_->flag, s_->f_val, - s_->alloc, (s_)->callbacks); -} -_Bool hs_print(struct hashset *_set_, FILE *fptr, const char *start, const char *separator, const char *end) -{ - fprintf(fptr, "%s", start); - size_t last = 0; - for (size_t i = _set_->capacity; i > 0; i--) - { - if ((_set_->buffer[i - 1]).state == CMC_ES_FILLED) - { - last = i - 1; - break; - } - } - for (size_t i = 0; i < _set_->capacity; i++) - { - struct hashset_entry *entry = &(_set_->buffer[i]); - if (entry->state == CMC_ES_FILLED) - { - if (!_set_->f_val->str(fptr, entry->value)) - return 0; - if (i + 1 < last) - fprintf(fptr, "%s", separator); - } - } - fprintf(fptr, "%s", end); - return 1; -} diff --git a/tests/src/tst_cmc_heap.c b/tests/src/tst_cmc_heap.c deleted file mode 100644 index f9af692..0000000 --- a/tests/src/tst_cmc_heap.c +++ /dev/null @@ -1,424 +0,0 @@ - -#include "tst_cmc_heap.h" - -static void h_impl_float_up(struct heap *_heap_, size_t index); -static void h_impl_float_down(struct heap *_heap_, size_t index); -struct heap *h_new(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val) -{ - return h_new_custom(capacity, HO, f_val, ((void *)0), ((void *)0)); -} -struct heap *h_new_custom(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val, - struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (capacity < 1) - return ((void *)0); - if (HO != CMC_MIN_HEAP && HO != CMC_MAX_HEAP) - return ((void *)0); - if (!f_val) - return ((void *)0); - if (!alloc) - alloc = &cmc_alloc_node_default; - struct heap *_heap_ = alloc->malloc(sizeof(struct heap)); - if (!_heap_) - return ((void *)0); - _heap_->buffer = alloc->calloc(capacity, sizeof(size_t)); - if (!_heap_->buffer) - { - alloc->free(_heap_); - return ((void *)0); - } - _heap_->capacity = capacity; - _heap_->count = 0; - _heap_->HO = HO; - _heap_->flag = CMC_FLAG_OK; - _heap_->f_val = f_val; - _heap_->alloc = alloc; - (_heap_)->callbacks = callbacks; - return _heap_; -} -void h_clear(struct heap *_heap_) -{ - if (_heap_->f_val->free) - { - for (size_t i = 0; i < _heap_->count; i++) - { - _heap_->f_val->free(_heap_->buffer[i]); - } - } - memset(_heap_->buffer, 0, sizeof(size_t) * _heap_->capacity); - _heap_->count = 0; - _heap_->flag = CMC_FLAG_OK; -} -void h_free(struct heap *_heap_) -{ - if (_heap_->f_val->free) - { - for (size_t i = 0; i < _heap_->count; i++) - { - _heap_->f_val->free(_heap_->buffer[i]); - } - } - _heap_->alloc->free(_heap_->buffer); - _heap_->alloc->free(_heap_); -} -void h_customize(struct heap *_heap_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (!alloc) - _heap_->alloc = &cmc_alloc_node_default; - else - _heap_->alloc = alloc; - (_heap_)->callbacks = callbacks; - _heap_->flag = CMC_FLAG_OK; -} -_Bool h_insert(struct heap *_heap_, size_t value) -{ - if (h_full(_heap_)) - { - if (!h_resize(_heap_, _heap_->count * 2)) - return 0; - } - _heap_->buffer[_heap_->count++] = value; - if (_heap_->count > 1) - { - h_impl_float_up(_heap_, _heap_->count - 1); - } - _heap_->flag = CMC_FLAG_OK; - if ((_heap_)->callbacks && (_heap_)->callbacks->create) - (_heap_)->callbacks->create(); - ; - return 1; -} -_Bool h_remove(struct heap *_heap_) -{ - if (h_empty(_heap_)) - { - _heap_->flag = CMC_FLAG_EMPTY; - return 0; - } - _heap_->buffer[0] = _heap_->buffer[_heap_->count - 1]; - _heap_->buffer[_heap_->count - 1] = (size_t){ 0 }; - _heap_->count--; - h_impl_float_down(_heap_, 0); - _heap_->flag = CMC_FLAG_OK; - if ((_heap_)->callbacks && (_heap_)->callbacks->delete) - (_heap_)->callbacks->delete (); - ; - return 1; -} -size_t h_peek(struct heap *_heap_) -{ - if (h_empty(_heap_)) - { - _heap_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - _heap_->flag = CMC_FLAG_OK; - if ((_heap_)->callbacks && (_heap_)->callbacks->read) - (_heap_)->callbacks->read(); - ; - return _heap_->buffer[0]; -} -_Bool h_contains(struct heap *_heap_, size_t value) -{ - _heap_->flag = CMC_FLAG_OK; - _Bool result = 0; - for (size_t i = 0; i < _heap_->count; i++) - { - if (_heap_->f_val->cmp(_heap_->buffer[i], value) == 0) - { - result = 1; - break; - } - } - if ((_heap_)->callbacks && (_heap_)->callbacks->read) - (_heap_)->callbacks->read(); - ; - return result; -} -_Bool h_empty(struct heap *_heap_) -{ - return _heap_->count == 0; -} -_Bool h_full(struct heap *_heap_) -{ - return _heap_->count >= _heap_->capacity; -} -size_t h_count(struct heap *_heap_) -{ - return _heap_->count; -} -size_t h_capacity(struct heap *_heap_) -{ - return _heap_->capacity; -} -int h_flag(struct heap *_heap_) -{ - return _heap_->flag; -} -_Bool h_resize(struct heap *_heap_, size_t capacity) -{ - _heap_->flag = CMC_FLAG_OK; - if (_heap_->capacity == capacity) - goto success; - if (capacity < _heap_->count) - { - _heap_->flag = CMC_FLAG_INVALID; - return 0; - } - size_t *new_buffer = _heap_->alloc->realloc(_heap_->buffer, sizeof(size_t) * capacity); - if (!new_buffer) - { - _heap_->flag = CMC_FLAG_ALLOC; - return 0; - } - _heap_->buffer = new_buffer; - _heap_->capacity = capacity; -success: - if ((_heap_)->callbacks && (_heap_)->callbacks->resize) - (_heap_)->callbacks->resize(); - ; - return 1; -} -struct heap *h_copy_of(struct heap *_heap_) -{ - struct heap *result = h_new_custom(_heap_->capacity, _heap_->HO, _heap_->f_val, _heap_->alloc, ((void *)0)); - if (!result) - { - _heap_->flag = CMC_FLAG_ERROR; - return ((void *)0); - } - (result)->callbacks = _heap_->callbacks; - if (_heap_->f_val->cpy) - { - for (size_t i = 0; i < _heap_->count; i++) - result->buffer[i] = _heap_->f_val->cpy(_heap_->buffer[i]); - } - else - memcpy(result->buffer, _heap_->buffer, sizeof(size_t) * _heap_->count); - result->count = _heap_->count; - _heap_->flag = CMC_FLAG_OK; - return result; -} -_Bool h_equals(struct heap *_heap1_, struct heap *_heap2_) -{ - _heap1_->flag = CMC_FLAG_OK; - _heap2_->flag = CMC_FLAG_OK; - if (_heap1_->count != _heap2_->count) - return 0; - for (size_t i = 0; i < _heap1_->count; i++) - { - if (_heap1_->f_val->cmp(_heap1_->buffer[i], _heap2_->buffer[i]) != 0) - return 0; - } - return 1; -} -static void h_impl_float_up(struct heap *_heap_, size_t index) -{ - size_t C = index; - size_t child = _heap_->buffer[C]; - size_t parent = _heap_->buffer[(index - 1) / 2]; - int mod = _heap_->HO; - while (C > 0 && _heap_->f_val->cmp(child, parent) * mod > 0) - { - size_t tmp = _heap_->buffer[C]; - _heap_->buffer[C] = _heap_->buffer[(C - 1) / 2]; - _heap_->buffer[(C - 1) / 2] = tmp; - C = (C - 1) / 2; - if (C == 0) - break; - child = _heap_->buffer[C]; - parent = _heap_->buffer[(C - 1) / 2]; - } -} -static void h_impl_float_down(struct heap *_heap_, size_t index) -{ - int mod = _heap_->HO; - while (index < _heap_->count) - { - size_t L = 2 * index + 1; - size_t R = 2 * index + 2; - size_t C = index; - if (L < _heap_->count && _heap_->f_val->cmp(_heap_->buffer[L], _heap_->buffer[C]) * mod > 0) - { - C = L; - } - if (R < _heap_->count && _heap_->f_val->cmp(_heap_->buffer[R], _heap_->buffer[C]) * mod > 0) - { - C = R; - } - if (C != index) - { - size_t tmp = _heap_->buffer[index]; - _heap_->buffer[index] = _heap_->buffer[C]; - _heap_->buffer[C] = tmp; - index = C; - } - else - break; - } -} -struct heap_iter h_iter_start(struct heap *target) -{ - struct heap_iter iter; - iter.target = target; - iter.cursor = 0; - iter.start = 1; - iter.end = h_empty(target); - return iter; -} -struct heap_iter h_iter_end(struct heap *target) -{ - struct heap_iter iter; - iter.target = target; - iter.cursor = 0; - iter.start = h_empty(target); - iter.end = 1; - if (!h_empty(target)) - iter.cursor = target->count - 1; - return iter; -} -_Bool h_iter_at_start(struct heap_iter *iter) -{ - return h_empty(iter->target) || iter->start; -} -_Bool h_iter_at_end(struct heap_iter *iter) -{ - return h_empty(iter->target) || iter->end; -} -_Bool h_iter_to_start(struct heap_iter *iter) -{ - if (!h_empty(iter->target)) - { - iter->cursor = 0; - iter->start = 1; - iter->end = h_empty(iter->target); - return 1; - } - return 0; -} -_Bool h_iter_to_end(struct heap_iter *iter) -{ - if (!h_empty(iter->target)) - { - iter->cursor = iter->target->count - 1; - iter->start = h_empty(iter->target); - iter->end = 1; - return 1; - } - return 0; -} -_Bool h_iter_next(struct heap_iter *iter) -{ - if (iter->end) - return 0; - if (iter->cursor + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - iter->start = h_empty(iter->target); - iter->cursor++; - return 1; -} -_Bool h_iter_prev(struct heap_iter *iter) -{ - if (iter->start) - return 0; - if (iter->cursor == 0) - { - iter->start = 1; - return 0; - } - iter->end = h_empty(iter->target); - iter->cursor--; - return 1; -} -_Bool h_iter_advance(struct heap_iter *iter, size_t steps) -{ - if (iter->end) - return 0; - if (iter->cursor + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - if (steps == 0 || iter->cursor + steps >= iter->target->count) - return 0; - if (iter->end) - return 0; - iter->start = h_empty(iter->target); - iter->cursor += steps; - return 1; -} -_Bool h_iter_rewind(struct heap_iter *iter, size_t steps) -{ - if (iter->start) - return 0; - if (iter->cursor == 0) - { - iter->start = 1; - return 0; - } - if (steps == 0 || iter->cursor < steps) - return 0; - iter->end = h_empty(iter->target); - iter->cursor -= steps; - return 1; -} -_Bool h_iter_go_to(struct heap_iter *iter, size_t index) -{ - if (index >= iter->target->count) - return 0; - if (iter->cursor > index) - return h_iter_rewind(iter, iter->cursor - index); - else if (iter->cursor < index) - return h_iter_advance(iter, index - iter->cursor); - return 1; -} -size_t h_iter_value(struct heap_iter *iter) -{ - if (h_empty(iter->target)) - return (size_t){ 0 }; - return iter->target->buffer[iter->cursor]; -} -size_t h_iter_index(struct heap_iter *iter) -{ - return iter->cursor; -} -_Bool h_to_string(struct heap *_heap_, FILE *fptr) -{ - struct heap *h_ = _heap_; - const char *t = h_->HO == 1 ? "MaxHeap" : "MinHeap"; - return 0 <= fprintf(fptr, - "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" - "I64u" - ", " - "count:%" - "I64u" - ", " - "type:%s, " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks: %p}", - "heap", "size_t", h_, h_->buffer, h_->capacity, h_->count, t, h_->flag, h_->f_val, h_->alloc, - (h_)->callbacks); -} -_Bool h_print(struct heap *_heap_, FILE *fptr, const char *start, const char *separator, const char *end) -{ - fprintf(fptr, "%s", start); - for (size_t i = 0; i < _heap_->count; i++) - { - if (!_heap_->f_val->str(fptr, _heap_->buffer[i])) - return 0; - if (i + 1 < _heap_->count) - fprintf(fptr, "%s", separator); - } - fprintf(fptr, "%s", end); - return 1; -} diff --git a/tests/src/tst_cmc_intervalheap.c b/tests/src/tst_cmc_intervalheap.c deleted file mode 100644 index e83970e..0000000 --- a/tests/src/tst_cmc_intervalheap.c +++ /dev/null @@ -1,686 +0,0 @@ - -#include "tst_cmc_intervalheap.h" - -static void ih_impl_float_up_max(struct intervalheap *_heap_); -static void ih_impl_float_up_min(struct intervalheap *_heap_); -static void ih_impl_float_down_max(struct intervalheap *_heap_); -static void ih_impl_float_down_min(struct intervalheap *_heap_); -struct intervalheap *ih_new(size_t capacity, struct intervalheap_fval *f_val) -{ - return ih_new_custom(capacity, f_val, ((void *)0), ((void *)0)); -} -struct intervalheap *ih_new_custom(size_t capacity, struct intervalheap_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) -{ - ; - if (capacity == 0 || capacity == 0xffffffffffffffffULL) - return ((void *)0); - if (!f_val) - return ((void *)0); - if (!alloc) - alloc = &cmc_alloc_node_default; - struct intervalheap *_heap_ = alloc->malloc(sizeof(struct intervalheap)); - if (!_heap_) - return ((void *)0); - capacity = (capacity + capacity % 2) / 2; - _heap_->buffer = alloc->calloc(capacity, sizeof(size_t[2])); - if (!_heap_->buffer) - { - alloc->free(_heap_); - return ((void *)0); - } - _heap_->capacity = capacity; - _heap_->size = 0; - _heap_->count = 0; - _heap_->flag = CMC_FLAG_OK; - _heap_->f_val = f_val; - _heap_->alloc = alloc; - (_heap_)->callbacks = callbacks; - return _heap_; -} -void ih_clear(struct intervalheap *_heap_) -{ - if (_heap_->f_val->free) - { - for (size_t i = 0; i < _heap_->count; i++) - { - _heap_->f_val->free(_heap_->buffer[i / 2][i % 2]); - } - } - memset(_heap_->buffer, 0, sizeof(size_t[2]) * _heap_->capacity); - _heap_->size = 0; - _heap_->count = 0; - _heap_->flag = CMC_FLAG_OK; -} -void ih_free(struct intervalheap *_heap_) -{ - if (_heap_->f_val->free) - { - for (size_t i = 0; i < _heap_->count; i++) - { - _heap_->f_val->free(_heap_->buffer[i / 2][i % 2]); - } - } - _heap_->alloc->free(_heap_->buffer); - _heap_->alloc->free(_heap_); -} -void ih_customize(struct intervalheap *_heap_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (!alloc) - _heap_->alloc = &cmc_alloc_node_default; - else - _heap_->alloc = alloc; - (_heap_)->callbacks = callbacks; - _heap_->flag = CMC_FLAG_OK; -} -_Bool ih_insert(struct intervalheap *_heap_, size_t value) -{ - if (ih_full(_heap_)) - { - if (!ih_resize(_heap_, _heap_->capacity * 4)) - return 0; - } - if (_heap_->count % 2 == 0) - { - _heap_->buffer[_heap_->size][0] = value; - _heap_->buffer[_heap_->size][1] = (size_t){ 0 }; - _heap_->size++; - } - else - { - size_t(*node)[2] = &(_heap_->buffer[_heap_->size - 1]); - if (_heap_->f_val->cmp((*node)[0], value) > 0) - { - (*node)[1] = (*node)[0]; - (*node)[0] = value; - } - else - { - (*node)[1] = value; - } - } - _heap_->count++; - _heap_->flag = CMC_FLAG_OK; - if (_heap_->count > 2) - { - size_t(*parent)[2] = &(_heap_->buffer[(_heap_->size - 2) / 2]); - if (_heap_->f_val->cmp((*parent)[0], value) > 0) - ih_impl_float_up_min(_heap_); - else if (_heap_->f_val->cmp((*parent)[1], value) < 0) - ih_impl_float_up_max(_heap_); - } - if ((_heap_)->callbacks && (_heap_)->callbacks->create) - (_heap_)->callbacks->create(); - ; - return 1; -} -_Bool ih_remove_max(struct intervalheap *_heap_) -{ - if (ih_empty(_heap_)) - { - _heap_->flag = CMC_FLAG_EMPTY; - return 0; - } - if (_heap_->count == 1) - { - _heap_->buffer[0][0] = (size_t){ 0 }; - _heap_->count--; - _heap_->size--; - goto success; - } - size_t(*last_node)[2] = &(_heap_->buffer[_heap_->size - 1]); - if (_heap_->count % 2 == 1) - { - _heap_->buffer[0][1] = (*last_node)[0]; - (*last_node)[0] = (size_t){ 0 }; - _heap_->size--; - } - else - { - _heap_->buffer[0][1] = (*last_node)[1]; - (*last_node)[1] = (size_t){ 0 }; - } - _heap_->count--; - ih_impl_float_down_max(_heap_); -success: - _heap_->flag = CMC_FLAG_OK; - if ((_heap_)->callbacks && (_heap_)->callbacks->delete) - (_heap_)->callbacks->delete (); - ; - return 1; -} -_Bool ih_remove_min(struct intervalheap *_heap_) -{ - if (ih_empty(_heap_)) - { - _heap_->flag = CMC_FLAG_EMPTY; - return 0; - } - if (_heap_->count == 1) - { - _heap_->buffer[0][0] = (size_t){ 0 }; - _heap_->count--; - _heap_->size--; - goto success; - } - size_t(*last_node)[2] = &(_heap_->buffer[_heap_->size - 1]); - _heap_->buffer[0][0] = (*last_node)[0]; - if (_heap_->count % 2 == 1) - { - (*last_node)[0] = (size_t){ 0 }; - _heap_->size--; - } - else - { - (*last_node)[0] = (*last_node)[1]; - (*last_node)[1] = (size_t){ 0 }; - } - _heap_->count--; - ih_impl_float_down_min(_heap_); -success: - _heap_->flag = CMC_FLAG_OK; - if ((_heap_)->callbacks && (_heap_)->callbacks->delete) - (_heap_)->callbacks->delete (); - ; - return 1; -} -_Bool ih_update_max(struct intervalheap *_heap_, size_t value) -{ - if (ih_empty(_heap_)) - { - _heap_->flag = CMC_FLAG_EMPTY; - return 0; - } - if (_heap_->count == 1) - { - _heap_->buffer[0][0] = value; - } - else if (_heap_->f_val->cmp(value, _heap_->buffer[0][0]) < 0) - { - _heap_->buffer[0][1] = _heap_->buffer[0][0]; - _heap_->buffer[0][0] = value; - ih_impl_float_down_max(_heap_); - } - else - { - _heap_->buffer[0][1] = value; - ih_impl_float_down_max(_heap_); - } - _heap_->flag = CMC_FLAG_OK; - if ((_heap_)->callbacks && (_heap_)->callbacks->update) - (_heap_)->callbacks->update(); - ; - return 1; -} -_Bool ih_update_min(struct intervalheap *_heap_, size_t value) -{ - if (ih_empty(_heap_)) - { - _heap_->flag = CMC_FLAG_EMPTY; - return 0; - } - if (_heap_->count == 1) - { - _heap_->buffer[0][0] = value; - } - else if (_heap_->f_val->cmp(value, _heap_->buffer[0][1]) > 0) - { - _heap_->buffer[0][0] = _heap_->buffer[0][1]; - _heap_->buffer[0][1] = value; - ih_impl_float_down_min(_heap_); - } - else - { - _heap_->buffer[0][0] = value; - ih_impl_float_down_min(_heap_); - } - _heap_->flag = CMC_FLAG_OK; - if ((_heap_)->callbacks && (_heap_)->callbacks->update) - (_heap_)->callbacks->update(); - ; - return 1; -} -size_t ih_max(struct intervalheap *_heap_) -{ - if (ih_empty(_heap_)) - { - _heap_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - _heap_->flag = CMC_FLAG_OK; - if ((_heap_)->callbacks && (_heap_)->callbacks->read) - (_heap_)->callbacks->read(); - ; - if (_heap_->count == 1) - return _heap_->buffer[0][0]; - return _heap_->buffer[0][1]; -} -size_t ih_min(struct intervalheap *_heap_) -{ - if (ih_empty(_heap_)) - { - _heap_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - _heap_->flag = CMC_FLAG_OK; - if ((_heap_)->callbacks && (_heap_)->callbacks->read) - (_heap_)->callbacks->read(); - ; - return _heap_->buffer[0][0]; -} -_Bool ih_contains(struct intervalheap *_heap_, size_t value) -{ - _heap_->flag = CMC_FLAG_OK; - _Bool result = 0; - for (size_t i = 0; i < _heap_->count; i++) - { - if (_heap_->f_val->cmp(_heap_->buffer[i / 2][i % 2], value) == 0) - { - result = 1; - break; - } - } - if ((_heap_)->callbacks && (_heap_)->callbacks->read) - (_heap_)->callbacks->read(); - ; - return result; -} -_Bool ih_empty(struct intervalheap *_heap_) -{ - return _heap_->count == 0; -} -_Bool ih_full(struct intervalheap *_heap_) -{ - return _heap_->size >= _heap_->capacity && _heap_->count % 2 == 0; -} -size_t ih_count(struct intervalheap *_heap_) -{ - return _heap_->count; -} -size_t ih_capacity(struct intervalheap *_heap_) -{ - return _heap_->capacity; -} -int ih_flag(struct intervalheap *_heap_) -{ - return _heap_->flag; -} -_Bool ih_resize(struct intervalheap *_heap_, size_t capacity) -{ - if (_heap_->capacity == capacity) - goto success; - if (capacity < _heap_->count) - { - _heap_->flag = CMC_FLAG_INVALID; - return 0; - } - if (capacity == 0xffffffffffffffffULL) - { - _heap_->flag = CMC_FLAG_ERROR; - return 0; - } - capacity += capacity % 2; - size_t(*new_buffer)[2] = _heap_->alloc->realloc(_heap_->buffer, sizeof(size_t[2]) * capacity); - if (!new_buffer) - { - _heap_->flag = CMC_FLAG_ALLOC; - return 0; - } - if (capacity > _heap_->capacity) - { - memset(new_buffer + _heap_->capacity, 0, sizeof(size_t[2]) * (capacity - _heap_->capacity)); - } - _heap_->buffer = new_buffer; - _heap_->capacity = capacity; -success: - _heap_->flag = CMC_FLAG_OK; - if ((_heap_)->callbacks && (_heap_)->callbacks->resize) - (_heap_)->callbacks->resize(); - ; - return 1; -} -struct intervalheap *ih_copy_of(struct intervalheap *_heap_) -{ - struct intervalheap *result = _heap_->alloc->malloc(sizeof(struct intervalheap)); - if (!result) - { - _heap_->flag = CMC_FLAG_ALLOC; - return ((void *)0); - } - memcpy(result, _heap_, sizeof(struct intervalheap)); - result->buffer = _heap_->alloc->malloc(sizeof(size_t[2]) * _heap_->capacity); - if (!result->buffer) - { - _heap_->alloc->free(result); - _heap_->flag = CMC_FLAG_ALLOC; - return ((void *)0); - } - if (_heap_->f_val->cpy) - { - for (size_t i = 0; i < _heap_->count; i++) - result->buffer[i / 2][i % 2] = _heap_->f_val->cpy(_heap_->buffer[i / 2][i % 2]); - } - else - memcpy(result->buffer, _heap_->buffer, sizeof(size_t[2]) * _heap_->capacity); - result->capacity = _heap_->capacity; - result->size = _heap_->size; - result->count = _heap_->count; - result->flag = CMC_FLAG_OK; - result->f_val = _heap_->f_val; - result->alloc = _heap_->alloc; - (result)->callbacks = _heap_->callbacks; - _heap_->flag = CMC_FLAG_OK; - return result; -} -_Bool ih_equals(struct intervalheap *_heap1_, struct intervalheap *_heap2_) -{ - _heap1_->flag = CMC_FLAG_OK; - _heap2_->flag = CMC_FLAG_OK; - if (_heap1_->count != _heap2_->count) - return 0; - for (size_t i = 0; i < _heap1_->count; i++) - { - size_t value1 = _heap1_->buffer[i / 2][i % 2]; - size_t value2 = _heap2_->buffer[i / 2][i % 2]; - if (_heap1_->f_val->cmp(value1, value2) != 0) - return 0; - } - return 1; -} -static void ih_impl_float_up_max(struct intervalheap *_heap_) -{ - size_t index = _heap_->size - 1; - size_t(*curr_node)[2] = &(_heap_->buffer[index]); - while (index > 0) - { - size_t P_index = (index - 1) / 2; - size_t(*parent)[2] = &(_heap_->buffer[P_index]); - if (index == _heap_->size - 1 && _heap_->count % 2 != 0) - { - if (_heap_->f_val->cmp((*curr_node)[0], (*parent)[1]) < 0) - break; - size_t tmp = (*curr_node)[0]; - (*curr_node)[0] = (*parent)[1]; - (*parent)[1] = tmp; - } - else - { - if (_heap_->f_val->cmp((*curr_node)[1], (*parent)[1]) < 0) - break; - size_t tmp = (*curr_node)[1]; - (*curr_node)[1] = (*parent)[1]; - (*parent)[1] = tmp; - } - index = P_index; - curr_node = parent; - } -} -static void ih_impl_float_up_min(struct intervalheap *_heap_) -{ - size_t index = _heap_->size - 1; - size_t(*curr_node)[2] = &(_heap_->buffer[index]); - while (index > 0) - { - size_t P_index = (index - 1) / 2; - size_t(*parent)[2] = &(_heap_->buffer[P_index]); - if (_heap_->f_val->cmp((*curr_node)[0], (*parent)[0]) >= 0) - break; - size_t tmp = (*curr_node)[0]; - (*curr_node)[0] = (*parent)[0]; - (*parent)[0] = tmp; - index = P_index; - curr_node = parent; - } -} -static void ih_impl_float_down_max(struct intervalheap *_heap_) -{ - size_t index = 0; - size_t(*curr_node)[2] = &(_heap_->buffer[index]); - while (1) - { - if (2 * index + 1 >= _heap_->size) - break; - size_t child; - size_t L_index = index * 2 + 1; - size_t R_index = index * 2 + 2; - if (R_index < _heap_->size) - { - size_t(*L)[2] = &(_heap_->buffer[L_index]); - size_t(*R)[2] = &(_heap_->buffer[R_index]); - if (R_index == _heap_->size - 1 && _heap_->count % 2 != 0) - child = _heap_->f_val->cmp((*L)[1], (*R)[0]) > 0 ? L_index : R_index; - else - child = _heap_->f_val->cmp((*L)[1], (*R)[1]) > 0 ? L_index : R_index; - } - else - child = L_index; - size_t(*child_node)[2] = &(_heap_->buffer[child]); - if (child == _heap_->size - 1 && _heap_->count % 2 != 0) - { - if (_heap_->f_val->cmp((*curr_node)[1], (*child_node)[0]) >= 0) - break; - size_t tmp = (*child_node)[0]; - (*child_node)[0] = (*curr_node)[1]; - (*curr_node)[1] = tmp; - } - else - { - if (_heap_->f_val->cmp((*curr_node)[1], (*child_node)[1]) >= 0) - break; - size_t tmp = (*child_node)[1]; - (*child_node)[1] = (*curr_node)[1]; - (*curr_node)[1] = tmp; - if (_heap_->f_val->cmp((*child_node)[0], (*child_node)[1]) > 0) - { - tmp = (*child_node)[0]; - (*child_node)[0] = (*child_node)[1]; - (*child_node)[1] = tmp; - } - } - index = child; - curr_node = child_node; - } -} -static void ih_impl_float_down_min(struct intervalheap *_heap_) -{ - size_t index = 0; - size_t(*curr_node)[2] = &(_heap_->buffer[index]); - while (1) - { - if (2 * index + 1 >= _heap_->size) - break; - size_t child; - size_t L_index = index * 2 + 1; - size_t R_index = index * 2 + 2; - if (R_index < _heap_->size) - { - size_t(*L)[2] = &(_heap_->buffer[L_index]); - size_t(*R)[2] = &(_heap_->buffer[R_index]); - child = _heap_->f_val->cmp((*L)[0], (*R)[0]) < 0 ? L_index : R_index; - } - else - child = L_index; - size_t(*child_node)[2] = &(_heap_->buffer[child]); - if (_heap_->f_val->cmp((*curr_node)[0], (*child_node)[0]) < 0) - break; - size_t tmp = (*child_node)[0]; - (*child_node)[0] = (*curr_node)[0]; - (*curr_node)[0] = tmp; - if (child != _heap_->size - 1 || _heap_->count % 2 == 0) - { - if (_heap_->f_val->cmp((*child_node)[0], (*child_node)[1]) > 0) - { - tmp = (*child_node)[0]; - (*child_node)[0] = (*child_node)[1]; - (*child_node)[1] = tmp; - } - } - index = child; - curr_node = child_node; - } -} -struct intervalheap_iter ih_iter_start(struct intervalheap *target) -{ - struct intervalheap_iter iter; - iter.target = target; - iter.cursor = 0; - iter.start = 1; - iter.end = ih_empty(target); - return iter; -} -struct intervalheap_iter ih_iter_end(struct intervalheap *target) -{ - struct intervalheap_iter iter; - iter.target = target; - iter.cursor = 0; - iter.start = ih_empty(target); - iter.end = 1; - if (!ih_empty(target)) - iter.cursor = target->count - 1; - return iter; -} -_Bool ih_iter_at_start(struct intervalheap_iter *iter) -{ - return ih_empty(iter->target) || iter->start; -} -_Bool ih_iter_at_end(struct intervalheap_iter *iter) -{ - return ih_empty(iter->target) || iter->end; -} -_Bool ih_iter_to_start(struct intervalheap_iter *iter) -{ - if (!ih_empty(iter->target)) - { - iter->cursor = 0; - iter->start = 1; - iter->end = ih_empty(iter->target); - return 1; - } - return 0; -} -_Bool ih_iter_to_end(struct intervalheap_iter *iter) -{ - if (!ih_empty(iter->target)) - { - iter->cursor = iter->target->count - 1; - iter->start = ih_empty(iter->target); - iter->end = 1; - return 1; - } - return 0; -} -_Bool ih_iter_next(struct intervalheap_iter *iter) -{ - if (iter->end) - return 0; - if (iter->cursor + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - iter->start = ih_empty(iter->target); - iter->cursor++; - return 1; -} -_Bool ih_iter_prev(struct intervalheap_iter *iter) -{ - if (iter->start) - return 0; - if (iter->cursor == 0) - { - iter->start = 1; - return 0; - } - iter->end = ih_empty(iter->target); - iter->cursor--; - return 1; -} -_Bool ih_iter_advance(struct intervalheap_iter *iter, size_t steps) -{ - if (iter->end) - return 0; - if (iter->cursor + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - if (steps == 0 || iter->cursor + steps >= iter->target->count) - return 0; - if (iter->end) - return 0; - iter->start = ih_empty(iter->target); - iter->cursor += steps; - return 1; -} -_Bool ih_iter_rewind(struct intervalheap_iter *iter, size_t steps) -{ - if (iter->start) - return 0; - if (iter->cursor == 0) - { - iter->start = 1; - return 0; - } - if (steps == 0 || iter->cursor < steps) - return 0; - iter->end = ih_empty(iter->target); - iter->cursor -= steps; - return 1; -} -_Bool ih_iter_go_to(struct intervalheap_iter *iter, size_t index) -{ - if (index >= iter->target->count) - return 0; - if (iter->cursor > index) - return ih_iter_rewind(iter, iter->cursor - index); - else if (iter->cursor < index) - return ih_iter_advance(iter, index - iter->cursor); - return 1; -} -size_t ih_iter_value(struct intervalheap_iter *iter) -{ - if (ih_empty(iter->target)) - return (size_t){ 0 }; - return iter->target->buffer[iter->cursor / 2][iter->cursor % 2]; -} -size_t ih_iter_index(struct intervalheap_iter *iter) -{ - return iter->cursor; -} -_Bool ih_to_string(struct intervalheap *_heap_, FILE *fptr) -{ - struct intervalheap *h_ = _heap_; - return 0 <= fprintf(fptr, - "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" - "I64u" - ", " - "size:%" - "I64u" - ", " - "count:%" - "I64u" - ", " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }", - "intervalheap", "size_t", h_, h_->buffer, h_->capacity, h_->size, h_->count, h_->flag, - h_->f_val, h_->alloc, (h_)->callbacks); -} -_Bool ih_print(struct intervalheap *_heap_, FILE *fptr, const char *start, const char *separator, const char *end) -{ - fprintf(fptr, "%s", start); - for (size_t i = 0; i < _heap_->count; i++) - { - if (!_heap_->f_val->str(fptr, _heap_->buffer[i / 2][i % 2])) - return 0; - if (i + 1 < _heap_->count) - fprintf(fptr, "%s", separator); - } - fprintf(fptr, "%s", end); - return 1; -} diff --git a/tests/src/tst_cmc_linkedlist.c b/tests/src/tst_cmc_linkedlist.c deleted file mode 100644 index 2587108..0000000 --- a/tests/src/tst_cmc_linkedlist.c +++ /dev/null @@ -1,683 +0,0 @@ - -#include "tst_cmc_linkedlist.h" - -struct linkedlist *ll_new(struct linkedlist_fval *f_val) -{ - return ll_new_custom(f_val, ((void *)0), ((void *)0)); -} -struct linkedlist *ll_new_custom(struct linkedlist_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) -{ - ; - if (!f_val) - return ((void *)0); - if (!alloc) - alloc = &cmc_alloc_node_default; - struct linkedlist *_list_ = alloc->malloc(sizeof(struct linkedlist)); - if (!_list_) - return ((void *)0); - _list_->count = 0; - _list_->head = ((void *)0); - _list_->tail = ((void *)0); - _list_->flag = CMC_FLAG_OK; - _list_->f_val = f_val; - _list_->alloc = alloc; - (_list_)->callbacks = callbacks; - return _list_; -} -void ll_clear(struct linkedlist *_list_) -{ - struct linkedlist_node *scan = _list_->head; - while (_list_->head != ((void *)0)) - { - _list_->head = _list_->head->next; - if (_list_->f_val->free) - { - _list_->f_val->free(scan->value); - } - _list_->alloc->free(scan); - scan = _list_->head; - } - _list_->count = 0; - _list_->head = ((void *)0); - _list_->tail = ((void *)0); - _list_->flag = CMC_FLAG_OK; -} -void ll_free(struct linkedlist *_list_) -{ - ll_clear(_list_); - _list_->alloc->free(_list_); -} -void ll_customize(struct linkedlist *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (!alloc) - _list_->alloc = &cmc_alloc_node_default; - else - _list_->alloc = alloc; - (_list_)->callbacks = callbacks; - _list_->flag = CMC_FLAG_OK; -} -_Bool ll_push_front(struct linkedlist *_list_, size_t value) -{ - struct linkedlist_node *_node_ = ll_new_node(_list_, value); - if (!_node_) - return 0; - if (ll_empty(_list_)) - { - _list_->head = _node_; - _list_->tail = _node_; - } - else - { - _node_->next = _list_->head; - _list_->head->prev = _node_; - _list_->head = _node_; - } - _list_->count++; - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->create) - (_list_)->callbacks->create(); - ; - return 1; -} -_Bool ll_push_at(struct linkedlist *_list_, size_t value, size_t index) -{ - if (index > _list_->count) - { - _list_->flag = CMC_FLAG_RANGE; - return 0; - } - if (index == 0) - { - return ll_push_front(_list_, value); - } - else if (index == _list_->count) - { - return ll_push_back(_list_, value); - } - struct linkedlist_node *_node_ = ll_new_node(_list_, value); - if (!_node_) - return 0; - struct linkedlist_node *scan = ll_get_node(_list_, index - 1); - _node_->next = scan->next; - _node_->prev = scan; - _node_->next->prev = _node_; - _node_->prev->next = _node_; - _list_->count++; - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->create) - (_list_)->callbacks->create(); - ; - return 1; -} -_Bool ll_push_back(struct linkedlist *_list_, size_t value) -{ - struct linkedlist_node *_node_ = ll_new_node(_list_, value); - if (!_node_) - return 0; - if (ll_empty(_list_)) - { - _list_->head = _node_; - _list_->tail = _node_; - } - else - { - _node_->prev = _list_->tail; - _list_->tail->next = _node_; - _list_->tail = _node_; - } - _list_->count++; - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->create) - (_list_)->callbacks->create(); - ; - return 1; -} -_Bool ll_pop_front(struct linkedlist *_list_) -{ - if (ll_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct linkedlist_node *_node_ = _list_->head; - _list_->head = _list_->head->next; - _list_->alloc->free(_node_); - if (_list_->head == ((void *)0)) - _list_->tail = ((void *)0); - else - _list_->head->prev = ((void *)0); - _list_->count--; - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->delete) - (_list_)->callbacks->delete (); - ; - return 1; -} -_Bool ll_pop_at(struct linkedlist *_list_, size_t index) -{ - if (ll_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return 0; - } - if (index >= _list_->count) - { - _list_->flag = CMC_FLAG_RANGE; - return 0; - } - if (index == 0) - { - return ll_pop_front(_list_); - } - else if (index == _list_->count - 1) - { - return ll_pop_back(_list_); - } - struct linkedlist_node *_node_ = ll_get_node(_list_, index); - if (!_node_) - return 0; - _node_->next->prev = _node_->prev; - _node_->prev->next = _node_->next; - _list_->alloc->free(_node_); - _list_->count--; - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->delete) - (_list_)->callbacks->delete (); - ; - return 1; -} -_Bool ll_pop_back(struct linkedlist *_list_) -{ - if (ll_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct linkedlist_node *_node_ = _list_->tail; - _list_->tail = _list_->tail->prev; - _list_->alloc->free(_node_); - if (_list_->tail == ((void *)0)) - _list_->head = ((void *)0); - else - _list_->tail->next = ((void *)0); - _list_->count--; - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->delete) - (_list_)->callbacks->delete (); - ; - return 1; -} -size_t ll_front(struct linkedlist *_list_) -{ - if (ll_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->read) - (_list_)->callbacks->read(); - ; - return _list_->head->value; -} -size_t ll_get(struct linkedlist *_list_, size_t index) -{ - if (ll_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - if (index >= _list_->count) - { - _list_->flag = CMC_FLAG_RANGE; - return (size_t){ 0 }; - } - struct linkedlist_node *scan = ll_get_node(_list_, index); - if (scan == ((void *)0)) - return (size_t){ 0 }; - if ((_list_)->callbacks && (_list_)->callbacks->read) - (_list_)->callbacks->read(); - ; - return scan->value; -} -size_t *ll_get_ref(struct linkedlist *_list_, size_t index) -{ - if (ll_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return ((void *)0); - } - if (index >= _list_->count) - { - _list_->flag = CMC_FLAG_RANGE; - return ((void *)0); - } - struct linkedlist_node *scan = ll_get_node(_list_, index); - if (scan == ((void *)0)) - return ((void *)0); - if ((_list_)->callbacks && (_list_)->callbacks->read) - (_list_)->callbacks->read(); - ; - return &(scan->value); -} -size_t ll_back(struct linkedlist *_list_) -{ - if (ll_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->read) - (_list_)->callbacks->read(); - ; - return _list_->tail->value; -} -_Bool ll_contains(struct linkedlist *_list_, size_t value) -{ - _list_->flag = CMC_FLAG_OK; - _Bool result = 0; - struct linkedlist_node *scan = _list_->head; - while (scan != ((void *)0)) - { - if (_list_->f_val->cmp(scan->value, value) == 0) - { - result = 1; - break; - } - scan = scan->next; - } - if ((_list_)->callbacks && (_list_)->callbacks->read) - (_list_)->callbacks->read(); - ; - return result; -} -_Bool ll_empty(struct linkedlist *_list_) -{ - return _list_->count == 0; -} -size_t ll_count(struct linkedlist *_list_) -{ - return _list_->count; -} -int ll_flag(struct linkedlist *_list_) -{ - return _list_->flag; -} -struct linkedlist *ll_copy_of(struct linkedlist *_list_) -{ - struct linkedlist *result = ll_new_custom(_list_->f_val, _list_->alloc, ((void *)0)); - if (!result) - return ((void *)0); - (result)->callbacks = _list_->callbacks; - struct linkedlist_node *scan = _list_->head; - while (scan != ((void *)0)) - { - struct linkedlist_node *new_node; - if (_list_->f_val->cpy) - new_node = ll_new_node(_list_, _list_->f_val->cpy(scan->value)); - else - new_node = ll_new_node(_list_, scan->value); - if (!result->head) - { - result->head = new_node; - result->tail = new_node; - } - else - { - new_node->prev = result->tail; - result->tail->next = new_node; - result->tail = new_node; - } - scan = scan->next; - } - result->count = _list_->count; - _list_->flag = CMC_FLAG_OK; - return result; -} -_Bool ll_equals(struct linkedlist *_list1_, struct linkedlist *_list2_) -{ - _list1_->flag = CMC_FLAG_OK; - _list2_->flag = CMC_FLAG_OK; - if (_list1_->count != _list2_->count) - return 0; - struct linkedlist_node *scan1 = _list1_->head; - struct linkedlist_node *scan2 = _list2_->head; - while (scan1 != ((void *)0) && scan2 != ((void *)0)) - { - if (_list1_->f_val->cmp(scan1->value, scan2->value) != 0) - return 0; - scan1 = scan1->next; - scan2 = scan2->next; - } - return 1; -} -struct linkedlist_iter ll_iter_start(struct linkedlist *target) -{ - struct linkedlist_iter iter; - iter.target = target; - iter.cursor = target->head; - iter.index = 0; - iter.start = 1; - iter.end = ll_empty(target); - return iter; -} -struct linkedlist_iter ll_iter_end(struct linkedlist *target) -{ - struct linkedlist_iter iter; - iter.target = target; - iter.cursor = target->tail; - iter.index = 0; - iter.start = ll_empty(target); - iter.end = 1; - if (!ll_empty(target)) - iter.index = target->count - 1; - return iter; -} -_Bool ll_iter_at_start(struct linkedlist_iter *iter) -{ - return ll_empty(iter->target) || iter->start; -} -_Bool ll_iter_at_end(struct linkedlist_iter *iter) -{ - return ll_empty(iter->target) || iter->end; -} -_Bool ll_iter_to_start(struct linkedlist_iter *iter) -{ - if (!ll_empty(iter->target)) - { - iter->cursor = iter->target->head; - iter->index = 0; - iter->start = 1; - iter->end = ll_empty(iter->target); - return 1; - } - return 0; -} -_Bool ll_iter_to_end(struct linkedlist_iter *iter) -{ - if (!ll_empty(iter->target)) - { - iter->cursor = iter->target->tail; - iter->index = iter->target->count - 1; - iter->start = ll_empty(iter->target); - iter->end = 1; - return 1; - } - return 0; -} -_Bool ll_iter_next(struct linkedlist_iter *iter) -{ - if (iter->end) - return 0; - if (iter->cursor->next == ((void *)0)) - { - iter->end = 1; - return 0; - } - iter->start = ll_empty(iter->target); - iter->cursor = iter->cursor->next; - iter->index++; - return 1; -} -_Bool ll_iter_prev(struct linkedlist_iter *iter) -{ - if (iter->start) - return 0; - if (iter->cursor->prev == ((void *)0)) - { - iter->start = 1; - return 0; - } - iter->end = ll_empty(iter->target); - iter->cursor = iter->cursor->prev; - iter->index--; - return 1; -} -_Bool ll_iter_advance(struct linkedlist_iter *iter, size_t steps) -{ - if (iter->end) - return 0; - if (iter->cursor->next == ((void *)0)) - { - iter->end = 1; - return 0; - } - if (steps == 0 || iter->index + steps >= iter->target->count) - return 0; - iter->start = ll_empty(iter->target); - iter->index += steps; - for (size_t i = 0; i < steps; i++) - iter->cursor = iter->cursor->next; - return 1; -} -_Bool ll_iter_rewind(struct linkedlist_iter *iter, size_t steps) -{ - if (iter->start) - return 0; - if (iter->cursor->prev == ((void *)0)) - { - iter->start = 1; - return 0; - } - if (steps == 0 || iter->index < steps) - return 0; - iter->end = ll_empty(iter->target); - iter->index -= steps; - for (size_t i = 0; i < steps; i++) - iter->cursor = iter->cursor->prev; - return 1; -} -_Bool ll_iter_go_to(struct linkedlist_iter *iter, size_t index) -{ - if (index >= iter->target->count) - return 0; - if (iter->index > index) - return ll_iter_rewind(iter, iter->index - index); - else if (iter->index < index) - return ll_iter_advance(iter, index - iter->index); - return 1; -} -size_t ll_iter_value(struct linkedlist_iter *iter) -{ - if (ll_empty(iter->target)) - return (size_t){ 0 }; - return iter->cursor->value; -} -size_t *ll_iter_rvalue(struct linkedlist_iter *iter) -{ - if (ll_empty(iter->target)) - return ((void *)0); - return &(iter->cursor->value); -} -size_t ll_iter_index(struct linkedlist_iter *iter) -{ - return iter->index; -} -struct linkedlist_node *ll_iter_node(struct linkedlist_iter *iter) -{ - return iter->cursor; -} -struct linkedlist_node *ll_new_node(struct linkedlist *_list_, size_t value) -{ - struct linkedlist_node *_node_ = _list_->alloc->malloc(sizeof(struct linkedlist_node)); - if (!_node_) - { - _list_->flag = CMC_FLAG_ALLOC; - return ((void *)0); - } - _node_->value = value; - _node_->next = ((void *)0); - _node_->prev = ((void *)0); - return _node_; -} -void ll_free_node(struct linkedlist *_list_, struct linkedlist_node *_node_) -{ - _list_->alloc->free(_node_); -} -struct linkedlist_node *ll_head(struct linkedlist *_list_) -{ - return _list_->head; -} -struct linkedlist_node *ll_get_node(struct linkedlist *_list_, size_t index) -{ - if (ll_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return ((void *)0); - } - if (index >= _list_->count) - { - _list_->flag = CMC_FLAG_RANGE; - return ((void *)0); - } - struct linkedlist_node *_node_ = ((void *)0); - if (index <= _list_->count / 2) - { - _node_ = _list_->head; - for (size_t i = 0; i < index; i++) - { - _node_ = _node_->next; - } - } - else - { - _node_ = _list_->tail; - for (size_t i = _list_->count - 1; i > index; i--) - { - _node_ = _node_->prev; - } - } - _list_->flag = CMC_FLAG_OK; - return _node_; -} -struct linkedlist_node *ll_tail(struct linkedlist *_list_) -{ - return _list_->tail; -} -_Bool ll_add_next(struct linkedlist *_owner_, struct linkedlist_node *_node_, size_t value) -{ - struct linkedlist_node *new_node = ll_new_node(_owner_, value); - if (!new_node) - return 0; - new_node->next = _node_->next; - if (_node_->next != ((void *)0)) - _node_->next->prev = new_node; - else - _owner_->tail = new_node; - new_node->prev = _node_; - _node_->next = new_node; - _owner_->count++; - _owner_->flag = CMC_FLAG_OK; - return 1; -} -_Bool ll_add_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_, size_t value) -{ - struct linkedlist_node *new_node = ll_new_node(_owner_, value); - if (!new_node) - return 0; - new_node->prev = _node_->prev; - if (_node_->prev != ((void *)0)) - _node_->prev->next = new_node; - else - _owner_->head = new_node; - new_node->next = _node_; - _node_->prev = new_node; - _owner_->count++; - _owner_->flag = CMC_FLAG_OK; - return 1; -} -_Bool ll_del_next(struct linkedlist *_owner_, struct linkedlist_node *_node_) -{ - if (_node_->next == ((void *)0)) - { - _owner_->flag = CMC_FLAG_INVALID; - return 0; - } - struct linkedlist_node *tmp = _node_->next; - _node_->next = _node_->next->next; - if (tmp->next != ((void *)0)) - tmp->next->prev = _node_; - else - _owner_->tail = _node_; - _owner_->alloc->free(tmp); - _owner_->count--; - _owner_->flag = CMC_FLAG_OK; - return 1; -} -_Bool ll_del_curr(struct linkedlist *_owner_, struct linkedlist_node *_node_) -{ - if (_node_->prev != ((void *)0)) - _node_->prev->next = _node_->next; - else - _owner_->head = _node_->next; - if (_node_->next != ((void *)0)) - _node_->next->prev = _node_->prev; - else - _owner_->tail = _node_->prev; - _owner_->alloc->free(_node_); - _owner_->count--; - _owner_->flag = CMC_FLAG_OK; - return 1; -} -_Bool ll_del_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_) -{ - if (_node_->prev == ((void *)0)) - { - _owner_->flag = CMC_FLAG_INVALID; - return 0; - } - struct linkedlist_node *tmp = _node_->prev; - _node_->prev = _node_->prev->prev; - if (tmp->prev != ((void *)0)) - tmp->prev->next = _node_; - else - _owner_->head = _node_; - _owner_->alloc->free(tmp); - _owner_->count--; - _owner_->flag = CMC_FLAG_OK; - return 1; -} -struct linkedlist_node *ll_next_node(struct linkedlist_node *_node_) -{ - return _node_->next; -} -struct linkedlist_node *ll_prev_node(struct linkedlist_node *_node_) -{ - return _node_->prev; -} -_Bool ll_to_string(struct linkedlist *_list_, FILE *fptr) -{ - struct linkedlist *l_ = _list_; - return 0 <= fprintf(fptr, - "struct %s<%s> " - "at %p { " - "count:%" - "I64u" - ", " - "head:%p, " - "tail:%p, " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }", - "linkedlist", "size_t", l_, l_->count, l_->head, l_->tail, l_->flag, l_->f_val, l_->alloc, - (l_)->callbacks); -} -_Bool ll_print(struct linkedlist *_list_, FILE *fptr, const char *start, const char *separator, const char *end) -{ - fprintf(fptr, "%s", start); - struct linkedlist_node *scan = _list_->head; - while (scan != ((void *)0)) - { - if (!_list_->f_val->str(fptr, scan->value)) - return 0; - scan = scan->next; - if (scan) - fprintf(fptr, "%s", separator); - } - fprintf(fptr, "%s", end); - return 1; -} diff --git a/tests/src/tst_cmc_list.c b/tests/src/tst_cmc_list.c deleted file mode 100644 index 6ada698..0000000 --- a/tests/src/tst_cmc_list.c +++ /dev/null @@ -1,643 +0,0 @@ - -#include "tst_cmc_list.h" - -struct list *l_new(size_t capacity, struct list_fval *f_val) -{ - return l_new_custom(capacity, f_val, ((void *)0), ((void *)0)); -} -struct list *l_new_custom(size_t capacity, struct list_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) -{ - ; - if (capacity < 1) - return ((void *)0); - if (!f_val) - return ((void *)0); - if (!alloc) - alloc = &cmc_alloc_node_default; - struct list *_list_ = alloc->malloc(sizeof(struct list)); - if (!_list_) - return ((void *)0); - _list_->buffer = alloc->calloc(capacity, sizeof(size_t)); - if (!_list_->buffer) - { - alloc->free(_list_); - return ((void *)0); - } - _list_->capacity = capacity; - _list_->count = 0; - _list_->flag = CMC_FLAG_OK; - _list_->f_val = f_val; - _list_->alloc = alloc; - (_list_)->callbacks = callbacks; - return _list_; -} -void l_clear(struct list *_list_) -{ - if (_list_->f_val->free) - { - for (size_t i = 0; i < _list_->count; i++) - _list_->f_val->free(_list_->buffer[i]); - } - memset(_list_->buffer, 0, sizeof(size_t) * _list_->capacity); - _list_->count = 0; - _list_->flag = CMC_FLAG_OK; -} -void l_free(struct list *_list_) -{ - if (_list_->f_val->free) - { - for (size_t i = 0; i < _list_->count; i++) - _list_->f_val->free(_list_->buffer[i]); - } - _list_->alloc->free(_list_->buffer); - _list_->alloc->free(_list_); -} -void l_customize(struct list *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (!alloc) - _list_->alloc = &cmc_alloc_node_default; - else - _list_->alloc = alloc; - (_list_)->callbacks = callbacks; - _list_->flag = CMC_FLAG_OK; -} -_Bool l_push_front(struct list *_list_, size_t value) -{ - if (l_full(_list_)) - { - if (!l_resize(_list_, _list_->count * 2)) - return 0; - } - if (!l_empty(_list_)) - { - memmove(_list_->buffer + 1, _list_->buffer, _list_->count * sizeof(size_t)); - } - _list_->buffer[0] = value; - _list_->count++; - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->create) - (_list_)->callbacks->create(); - ; - return 1; -} -_Bool l_push_at(struct list *_list_, size_t value, size_t index) -{ - if (index > _list_->count) - { - _list_->flag = CMC_FLAG_RANGE; - return 0; - } - if (l_full(_list_)) - { - if (!l_resize(_list_, _list_->count * 2)) - return 0; - } - memmove(_list_->buffer + index + 1, _list_->buffer + index, (_list_->count - index) * sizeof(size_t)); - _list_->buffer[index] = value; - _list_->count++; - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->create) - (_list_)->callbacks->create(); - ; - return 1; -} -_Bool l_push_back(struct list *_list_, size_t value) -{ - if (l_full(_list_)) - { - if (!l_resize(_list_, _list_->count * 2)) - return 0; - } - _list_->buffer[_list_->count++] = value; - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->create) - (_list_)->callbacks->create(); - ; - return 1; -} -_Bool l_pop_front(struct list *_list_) -{ - if (l_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return 0; - } - memmove(_list_->buffer, _list_->buffer + 1, (_list_->count - 1) * sizeof(size_t)); - _list_->buffer[--_list_->count] = (size_t){ 0 }; - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->delete) - (_list_)->callbacks->delete (); - ; - return 1; -} -_Bool l_pop_at(struct list *_list_, size_t index) -{ - if (l_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return 0; - } - if (index >= _list_->count) - { - _list_->flag = CMC_FLAG_RANGE; - return 0; - } - memmove(_list_->buffer + index, _list_->buffer + index + 1, (_list_->count - index - 1) * sizeof(size_t)); - _list_->buffer[--_list_->count] = (size_t){ 0 }; - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->delete) - (_list_)->callbacks->delete (); - ; - return 1; -} -_Bool l_pop_back(struct list *_list_) -{ - if (l_empty(_list_)) - return 0; - _list_->buffer[--_list_->count] = (size_t){ 0 }; - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->delete) - (_list_)->callbacks->delete (); - ; - return 1; -} -size_t l_front(struct list *_list_) -{ - if (l_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->read) - (_list_)->callbacks->read(); - ; - return _list_->buffer[0]; -} -size_t l_get(struct list *_list_, size_t index) -{ - if (l_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - if (index >= _list_->count) - { - _list_->flag = CMC_FLAG_RANGE; - return (size_t){ 0 }; - } - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->read) - (_list_)->callbacks->read(); - ; - return _list_->buffer[index]; -} -size_t *l_get_ref(struct list *_list_, size_t index) -{ - if (l_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return ((void *)0); - } - if (index >= _list_->count) - { - _list_->flag = CMC_FLAG_RANGE; - return ((void *)0); - } - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->read) - (_list_)->callbacks->read(); - ; - return &(_list_->buffer[index]); -} -size_t l_back(struct list *_list_) -{ - if (l_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->read) - (_list_)->callbacks->read(); - ; - return _list_->buffer[_list_->count - 1]; -} -size_t l_index_of(struct list *_list_, size_t value, _Bool from_start) -{ - _list_->flag = CMC_FLAG_OK; - size_t result = _list_->count; - if (from_start) - { - for (size_t i = 0; i < _list_->count; i++) - { - if (_list_->f_val->cmp(_list_->buffer[i], value) == 0) - { - result = i; - break; - } - } - } - else - { - for (size_t i = _list_->count; i > 0; i--) - { - if (_list_->f_val->cmp(_list_->buffer[i - 1], value) == 0) - { - result = i - 1; - break; - } - } - } - if ((_list_)->callbacks && (_list_)->callbacks->read) - (_list_)->callbacks->read(); - ; - return result; -} -_Bool l_contains(struct list *_list_, size_t value) -{ - _list_->flag = CMC_FLAG_OK; - _Bool result = 0; - for (size_t i = 0; i < _list_->count; i++) - { - if (_list_->f_val->cmp(_list_->buffer[i], value) == 0) - { - result = 1; - break; - } - } - if ((_list_)->callbacks && (_list_)->callbacks->read) - (_list_)->callbacks->read(); - ; - return result; -} -_Bool l_empty(struct list *_list_) -{ - return _list_->count == 0; -} -_Bool l_full(struct list *_list_) -{ - return _list_->count >= _list_->capacity; -} -size_t l_count(struct list *_list_) -{ - return _list_->count; -} -_Bool l_fits(struct list *_list_, size_t size) -{ - return _list_->count + size <= _list_->capacity; -} -size_t l_capacity(struct list *_list_) -{ - return _list_->capacity; -} -int l_flag(struct list *_list_) -{ - return _list_->flag; -} -_Bool l_resize(struct list *_list_, size_t capacity) -{ - _list_->flag = CMC_FLAG_OK; - if (_list_->capacity == capacity) - return 1; - if (capacity < _list_->count) - { - _list_->flag = CMC_FLAG_INVALID; - return 0; - } - size_t *new_buffer = _list_->alloc->realloc(_list_->buffer, sizeof(size_t) * capacity); - if (!new_buffer) - { - _list_->flag = CMC_FLAG_ALLOC; - return 0; - } - _list_->buffer = new_buffer; - _list_->capacity = capacity; - if ((_list_)->callbacks && (_list_)->callbacks->resize) - (_list_)->callbacks->resize(); - ; - return 1; -} -struct list *l_copy_of(struct list *_list_) -{ - struct list *result = l_new_custom(_list_->capacity, _list_->f_val, _list_->alloc, ((void *)0)); - if (!result) - { - _list_->flag = CMC_FLAG_ALLOC; - return ((void *)0); - } - (result)->callbacks = _list_->callbacks; - if (_list_->f_val->cpy) - { - for (size_t i = 0; i < _list_->count; i++) - result->buffer[i] = _list_->f_val->cpy(_list_->buffer[i]); - } - else - memcpy(result->buffer, _list_->buffer, sizeof(size_t) * _list_->count); - result->count = _list_->count; - _list_->flag = CMC_FLAG_OK; - return result; -} -_Bool l_equals(struct list *_list1_, struct list *_list2_) -{ - _list1_->flag = CMC_FLAG_OK; - _list2_->flag = CMC_FLAG_OK; - if (_list1_->count != _list2_->count) - return 0; - for (size_t i = 0; i < _list1_->count; i++) - { - if (0 != _list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i])) - return 0; - } - return 1; -} -struct list_iter l_iter_start(struct list *target) -{ - struct list_iter iter; - iter.target = target; - iter.cursor = 0; - iter.start = 1; - iter.end = l_empty(target); - return iter; -} -struct list_iter l_iter_end(struct list *target) -{ - struct list_iter iter; - iter.target = target; - iter.cursor = 0; - iter.start = l_empty(target); - iter.end = 1; - if (!l_empty(target)) - iter.cursor = target->count - 1; - return iter; -} -_Bool l_iter_at_start(struct list_iter *iter) -{ - return l_empty(iter->target) || iter->start; -} -_Bool l_iter_at_end(struct list_iter *iter) -{ - return l_empty(iter->target) || iter->end; -} -_Bool l_iter_to_start(struct list_iter *iter) -{ - if (!l_empty(iter->target)) - { - iter->cursor = 0; - iter->start = 1; - iter->end = l_empty(iter->target); - return 1; - } - return 0; -} -_Bool l_iter_to_end(struct list_iter *iter) -{ - if (!l_empty(iter->target)) - { - iter->start = l_empty(iter->target); - iter->cursor = iter->target->count - 1; - iter->end = 1; - return 1; - } - return 0; -} -_Bool l_iter_next(struct list_iter *iter) -{ - if (iter->end) - return 0; - if (iter->cursor + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - iter->start = l_empty(iter->target); - iter->cursor++; - return 1; -} -_Bool l_iter_prev(struct list_iter *iter) -{ - if (iter->start) - return 0; - if (iter->cursor == 0) - { - iter->start = 1; - return 0; - } - iter->end = l_empty(iter->target); - iter->cursor--; - return 1; -} -_Bool l_iter_advance(struct list_iter *iter, size_t steps) -{ - if (iter->end) - return 0; - if (iter->cursor + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - if (steps == 0 || iter->cursor + steps >= iter->target->count) - return 0; - iter->start = l_empty(iter->target); - iter->cursor += steps; - return 1; -} -_Bool l_iter_rewind(struct list_iter *iter, size_t steps) -{ - if (iter->start) - return 0; - if (iter->cursor == 0) - { - iter->start = 1; - return 0; - } - if (steps == 0 || iter->cursor < steps) - return 0; - iter->end = l_empty(iter->target); - iter->cursor -= steps; - return 1; -} -_Bool l_iter_go_to(struct list_iter *iter, size_t index) -{ - if (index >= iter->target->count) - return 0; - if (iter->cursor > index) - return l_iter_rewind(iter, iter->cursor - index); - else if (iter->cursor < index) - return l_iter_advance(iter, index - iter->cursor); - return 1; -} -size_t l_iter_value(struct list_iter *iter) -{ - if (l_empty(iter->target)) - return (size_t){ 0 }; - return iter->target->buffer[iter->cursor]; -} -size_t *l_iter_rvalue(struct list_iter *iter) -{ - if (l_empty(iter->target)) - return ((void *)0); - return &(iter->target->buffer[iter->cursor]); -} -size_t l_iter_index(struct list_iter *iter) -{ - return iter->cursor; -} -_Bool l_seq_push_front(struct list *_list_, size_t *values, size_t size) -{ - if (size == 0) - { - _list_->flag = CMC_FLAG_INVALID; - return 0; - } - if (!l_fits(_list_, size)) - { - if (!l_resize(_list_, _list_->count + size)) - return 0; - } - memmove(_list_->buffer + size, _list_->buffer, _list_->count * sizeof(size_t)); - memcpy(_list_->buffer, values, size * sizeof(size_t)); - _list_->count += size; - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->create) - (_list_)->callbacks->create(); - ; - return 1; -} -_Bool l_seq_push_at(struct list *_list_, size_t *values, size_t size, size_t index) -{ - if (size == 0) - { - _list_->flag = CMC_FLAG_INVALID; - return 0; - } - if (index > _list_->count) - { - _list_->flag = CMC_FLAG_RANGE; - return 0; - } - if (index == 0) - return l_seq_push_front(_list_, values, size); - else if (index == _list_->count) - return l_seq_push_back(_list_, values, size); - if (!l_fits(_list_, size)) - { - if (!l_resize(_list_, _list_->count + size)) - return 0; - } - memmove(_list_->buffer + index + size, _list_->buffer + index, (_list_->count - index) * sizeof(size_t)); - memcpy(_list_->buffer + index, values, size * sizeof(size_t)); - _list_->count += size; - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->create) - (_list_)->callbacks->create(); - ; - return 1; -} -_Bool l_seq_push_back(struct list *_list_, size_t *values, size_t size) -{ - if (size == 0) - { - _list_->flag = CMC_FLAG_INVALID; - return 0; - } - if (!l_fits(_list_, size)) - { - if (!l_resize(_list_, _list_->count + size)) - return 0; - } - memcpy(_list_->buffer + _list_->count, values, size * sizeof(size_t)); - _list_->count += size; - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->create) - (_list_)->callbacks->create(); - ; - return 1; -} -_Bool l_seq_pop_at(struct list *_list_, size_t from, size_t to) -{ - if (from > to) - { - _list_->flag = CMC_FLAG_INVALID; - return 0; - } - if (to >= _list_->count) - { - _list_->flag = CMC_FLAG_RANGE; - return 0; - } - size_t length = (to - from + 1); - memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(size_t)); - memset(_list_->buffer + _list_->count - length, 0, length * sizeof(size_t)); - _list_->count -= to - from + 1; - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->delete) - (_list_)->callbacks->delete (); - ; - return 1; -} -struct list *l_seq_sublist(struct list *_list_, size_t from, size_t to) -{ - if (from > to) - { - _list_->flag = CMC_FLAG_INVALID; - return ((void *)0); - } - if (to >= _list_->count) - { - _list_->flag = CMC_FLAG_RANGE; - return ((void *)0); - } - size_t length = to - from + 1; - struct list *result = l_new_custom(length, _list_->f_val, _list_->alloc, (_list_)->callbacks); - if (!result) - { - _list_->flag = CMC_FLAG_ALLOC; - return ((void *)0); - } - memcpy(result->buffer, _list_->buffer, length * sizeof(size_t)); - memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(size_t)); - memset(_list_->buffer + _list_->count - length, 0, length * sizeof(size_t)); - _list_->count -= length; - result->count = length; - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->delete) - (_list_)->callbacks->delete (); - ; - return result; -} -_Bool l_to_string(struct list *_list_, FILE *fptr) -{ - struct list *l_ = _list_; - return 0 <= fprintf(fptr, - "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" - "I64u" - ", " - "count:%" - "I64u" - ", " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }", - "list", "size_t", l_, l_->buffer, l_->capacity, l_->count, l_->flag, l_->f_val, l_->alloc, - (l_)->callbacks); -} -_Bool l_print(struct list *_list_, FILE *fptr, const char *start, const char *separator, const char *end) -{ - fprintf(fptr, "%s", start); - for (size_t i = 0; i < _list_->count; i++) - { - if (!_list_->f_val->str(fptr, _list_->buffer[i])) - return 0; - if (i + 1 < _list_->count) - fprintf(fptr, "%s", separator); - } - fprintf(fptr, "%s", end); - return 1; -} diff --git a/tests/src/tst_cmc_queue.c b/tests/src/tst_cmc_queue.c deleted file mode 100644 index 82dc6cb..0000000 --- a/tests/src/tst_cmc_queue.c +++ /dev/null @@ -1,431 +0,0 @@ - -#include "tst_cmc_queue.h" - -struct queue *q_new(size_t capacity, struct queue_fval *f_val) -{ - return q_new_custom(capacity, f_val, ((void *)0), ((void *)0)); -} -struct queue *q_new_custom(size_t capacity, struct queue_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) -{ - ; - if (capacity < 1) - return ((void *)0); - if (!f_val) - return ((void *)0); - if (!alloc) - alloc = &cmc_alloc_node_default; - struct queue *_queue_ = alloc->malloc(sizeof(struct queue)); - if (!_queue_) - return ((void *)0); - _queue_->buffer = alloc->calloc(capacity, sizeof(size_t)); - if (!_queue_->buffer) - { - alloc->free(_queue_); - return ((void *)0); - } - _queue_->capacity = capacity; - _queue_->count = 0; - _queue_->front = 0; - _queue_->back = 0; - _queue_->flag = CMC_FLAG_OK; - _queue_->f_val = f_val; - _queue_->alloc = alloc; - (_queue_)->callbacks = callbacks; - return _queue_; -} -void q_clear(struct queue *_queue_) -{ - if (_queue_->f_val->free) - { - for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) - { - _queue_->f_val->free(_queue_->buffer[i]); - i = (i + 1) % _queue_->capacity; - } - } - memset(_queue_->buffer, 0, sizeof(size_t) * _queue_->capacity); - _queue_->count = 0; - _queue_->front = 0; - _queue_->back = 0; - _queue_->flag = CMC_FLAG_OK; -} -void q_free(struct queue *_queue_) -{ - if (_queue_->f_val->free) - { - for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) - { - _queue_->f_val->free(_queue_->buffer[i]); - i = (i + 1) % _queue_->capacity; - } - } - _queue_->alloc->free(_queue_->buffer); - _queue_->alloc->free(_queue_); -} -void q_customize(struct queue *_queue_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (!alloc) - _queue_->alloc = &cmc_alloc_node_default; - else - _queue_->alloc = alloc; - (_queue_)->callbacks = callbacks; - _queue_->flag = CMC_FLAG_OK; -} -_Bool q_enqueue(struct queue *_queue_, size_t value) -{ - if (q_full(_queue_)) - { - if (!q_resize(_queue_, _queue_->capacity * 2)) - return 0; - } - _queue_->buffer[_queue_->back] = value; - _queue_->back = (_queue_->back == _queue_->capacity - 1) ? 0 : _queue_->back + 1; - _queue_->count++; - _queue_->flag = CMC_FLAG_OK; - if ((_queue_)->callbacks && (_queue_)->callbacks->create) - (_queue_)->callbacks->create(); - ; - return 1; -} -_Bool q_dequeue(struct queue *_queue_) -{ - if (q_empty(_queue_)) - { - _queue_->flag = CMC_FLAG_EMPTY; - return 0; - } - _queue_->buffer[_queue_->front] = (size_t){ 0 }; - _queue_->front = (_queue_->front == _queue_->capacity - 1) ? 0 : _queue_->front + 1; - _queue_->count--; - _queue_->flag = CMC_FLAG_OK; - if ((_queue_)->callbacks && (_queue_)->callbacks->delete) - (_queue_)->callbacks->delete (); - ; - return 1; -} -size_t q_peek(struct queue *_queue_) -{ - if (q_empty(_queue_)) - { - _queue_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - _queue_->flag = CMC_FLAG_OK; - if ((_queue_)->callbacks && (_queue_)->callbacks->read) - (_queue_)->callbacks->read(); - ; - return _queue_->buffer[_queue_->front]; -} -_Bool q_contains(struct queue *_queue_, size_t value) -{ - _queue_->flag = CMC_FLAG_OK; - _Bool result = 0; - for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) - { - if (_queue_->f_val->cmp(_queue_->buffer[i], value) == 0) - { - result = 1; - break; - } - i = (i + 1) % _queue_->capacity; - } - if ((_queue_)->callbacks && (_queue_)->callbacks->read) - (_queue_)->callbacks->read(); - ; - return result; -} -_Bool q_empty(struct queue *_queue_) -{ - return _queue_->count == 0; -} -_Bool q_full(struct queue *_queue_) -{ - return _queue_->count >= _queue_->capacity; -} -size_t q_count(struct queue *_queue_) -{ - return _queue_->count; -} -size_t q_capacity(struct queue *_queue_) -{ - return _queue_->capacity; -} -int q_flag(struct queue *_queue_) -{ - return _queue_->flag; -} -_Bool q_resize(struct queue *_queue_, size_t capacity) -{ - if (_queue_->capacity == capacity) - goto success; - if (capacity < _queue_->count) - { - _queue_->flag = CMC_FLAG_INVALID; - return 0; - } - size_t *new_buffer = _queue_->alloc->malloc(sizeof(size_t) * capacity); - if (!new_buffer) - { - _queue_->flag = CMC_FLAG_ALLOC; - return 0; - } - for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) - { - new_buffer[j] = _queue_->buffer[i]; - i = (i + 1) % _queue_->capacity; - } - _queue_->alloc->free(_queue_->buffer); - _queue_->buffer = new_buffer; - _queue_->capacity = capacity; - _queue_->front = 0; - _queue_->back = _queue_->count; -success: - _queue_->flag = CMC_FLAG_OK; - if ((_queue_)->callbacks && (_queue_)->callbacks->resize) - (_queue_)->callbacks->resize(); - ; - return 1; -} -struct queue *q_copy_of(struct queue *_queue_) -{ - struct queue *result = q_new_custom(_queue_->capacity, _queue_->f_val, _queue_->alloc, ((void *)0)); - if (!result) - { - _queue_->flag = CMC_FLAG_ERROR; - return ((void *)0); - } - (result)->callbacks = _queue_->callbacks; - if (_queue_->f_val->cpy) - { - for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) - { - result->buffer[j] = _queue_->f_val->cpy(_queue_->buffer[i]); - i = (i + 1) % _queue_->capacity; - } - } - else - { - for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) - { - result->buffer[j] = _queue_->buffer[i]; - i = (i + 1) % _queue_->capacity; - } - } - result->count = _queue_->count; - result->front = 0; - result->back = _queue_->count; - _queue_->flag = CMC_FLAG_OK; - return result; -} -_Bool q_equals(struct queue *_queue1_, struct queue *_queue2_) -{ - _queue1_->flag = CMC_FLAG_OK; - _queue2_->flag = CMC_FLAG_OK; - if (_queue1_->count != _queue2_->count) - return 0; - size_t i, j, k; - for (i = _queue1_->front, j = _queue2_->front, k = 0; k < _queue1_->count; k++) - { - if (_queue1_->f_val->cmp(_queue1_->buffer[i], _queue2_->buffer[j]) != 0) - return 0; - i = (i + 1) % _queue1_->capacity; - j = (j + 1) % _queue2_->capacity; - } - return 1; -} -struct queue_iter q_iter_start(struct queue *target) -{ - struct queue_iter iter; - iter.target = target; - iter.cursor = target->front; - iter.index = 0; - iter.start = 1; - iter.end = q_empty(target); - return iter; -} -struct queue_iter q_iter_end(struct queue *target) -{ - struct queue_iter iter; - iter.target = target; - if (!q_empty(target)) - { - if (iter.target->back == 0) - iter.cursor = iter.target->capacity - 1; - else - iter.cursor = iter.target->back - 1; - iter.index = iter.target->count - 1; - } - else - { - iter.cursor = 0; - iter.index = 0; - } - iter.start = q_empty(target); - iter.end = 1; - return iter; -} -_Bool q_iter_at_start(struct queue_iter *iter) -{ - return q_empty(iter->target) || iter->start; -} -_Bool q_iter_at_end(struct queue_iter *iter) -{ - return q_empty(iter->target) || iter->end; -} -_Bool q_iter_to_start(struct queue_iter *iter) -{ - if (!q_empty(iter->target)) - { - iter->cursor = iter->target->front; - iter->index = 0; - iter->start = 1; - iter->end = 0; - return 1; - } - return 0; -} -_Bool q_iter_to_end(struct queue_iter *iter) -{ - if (!q_empty(iter->target)) - { - if (iter->target->back == 0) - iter->cursor = iter->target->capacity - 1; - else - iter->cursor = iter->target->back - 1; - iter->index = iter->target->count - 1; - iter->start = 0; - iter->end = 1; - return 1; - } - return 0; -} -_Bool q_iter_next(struct queue_iter *iter) -{ - if (iter->end) - return 0; - if (iter->index + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - iter->start = q_empty(iter->target); - iter->cursor = (iter->cursor + 1) % (iter->target->capacity); - iter->index++; - return 1; -} -_Bool q_iter_prev(struct queue_iter *iter) -{ - if (iter->start) - return 0; - if (iter->index == 0) - { - iter->start = 1; - return 0; - } - iter->end = q_empty(iter->target); - iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1; - iter->index--; - return 1; -} -_Bool q_iter_advance(struct queue_iter *iter, size_t steps) -{ - if (iter->end) - return 0; - if (iter->index + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - if (steps == 0 || iter->index + steps >= iter->target->count) - return 0; - iter->start = q_empty(iter->target); - iter->index += steps; - iter->cursor = (iter->cursor + steps) % iter->target->capacity; - return 1; -} -_Bool q_iter_rewind(struct queue_iter *iter, size_t steps) -{ - if (iter->start) - return 0; - if (iter->index == 0) - { - iter->start = 1; - return 0; - } - if (steps == 0 || iter->index < steps) - return 0; - iter->end = q_empty(iter->target); - iter->index -= steps; - if (iter->cursor < steps) - iter->cursor += iter->target->capacity; - iter->cursor -= steps; - return 1; -} -_Bool q_iter_go_to(struct queue_iter *iter, size_t index) -{ - if (index >= iter->target->count) - return 0; - if (iter->index > index) - return q_iter_rewind(iter, iter->index - index); - else if (iter->index < index) - return q_iter_advance(iter, index - iter->index); - return 1; -} -size_t q_iter_value(struct queue_iter *iter) -{ - if (q_empty(iter->target)) - return (size_t){ 0 }; - return iter->target->buffer[iter->cursor]; -} -size_t *q_iter_rvalue(struct queue_iter *iter) -{ - if (q_empty(iter->target)) - return ((void *)0); - return &(iter->target->buffer[iter->cursor]); -} -size_t q_iter_index(struct queue_iter *iter) -{ - return iter->index; -} -_Bool q_to_string(struct queue *_queue_, FILE *fptr) -{ - struct queue *q_ = _queue_; - return 0 <= fprintf(fptr, - "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" - "I64u" - ", " - "count:%" - "I64u" - ", " - "front:%" - "I64u" - ", " - "back:%" - "I64u" - ", " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }", - "queue", "size_t", q_, q_->buffer, q_->capacity, q_->count, q_->front, q_->back, q_->flag, - q_->f_val, q_->alloc, (q_)->callbacks); -} -_Bool q_print(struct queue *_queue_, FILE *fptr, const char *start, const char *separator, const char *end) -{ - fprintf(fptr, "%s", start); - for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) - { - if (!_queue_->f_val->str(fptr, _queue_->buffer[i])) - return 0; - i = (i + 1) % _queue_->capacity; - if (j + 1 < _queue_->count) - fprintf(fptr, "%s", separator); - } - fprintf(fptr, "%s", end); - return 1; -} diff --git a/tests/src/tst_cmc_sortedlist.c b/tests/src/tst_cmc_sortedlist.c deleted file mode 100644 index ae46830..0000000 --- a/tests/src/tst_cmc_sortedlist.c +++ /dev/null @@ -1,512 +0,0 @@ - -#include "tst_cmc_sortedlist.h" - -static size_t sl_impl_binary_search_first(struct sortedlist *_list_, size_t value); -static size_t sl_impl_binary_search_last(struct sortedlist *_list_, size_t value); -void sl_impl_sort_quicksort(size_t *array, int (*cmp)(size_t, size_t), size_t low, size_t high); -void sl_impl_sort_insertion(size_t *array, int (*cmp)(size_t, size_t), size_t low, size_t high); -struct sortedlist *sl_new(size_t capacity, struct sortedlist_fval *f_val) -{ - return sl_new_custom(capacity, f_val, ((void *)0), ((void *)0)); -} -struct sortedlist *sl_new_custom(size_t capacity, struct sortedlist_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) -{ - ; - if (capacity < 1) - return ((void *)0); - if (!alloc) - alloc = &cmc_alloc_node_default; - struct sortedlist *_list_ = alloc->malloc(sizeof(struct sortedlist)); - if (!_list_) - return ((void *)0); - _list_->buffer = alloc->calloc(capacity, sizeof(size_t)); - if (!_list_->buffer) - { - alloc->free(_list_); - return ((void *)0); - } - _list_->capacity = capacity; - _list_->count = 0; - _list_->is_sorted = 0; - _list_->flag = CMC_FLAG_OK; - _list_->f_val = f_val; - _list_->alloc = alloc; - (_list_)->callbacks = callbacks; - return _list_; -} -void sl_clear(struct sortedlist *_list_) -{ - if (_list_->f_val->free) - { - for (size_t i = 0; i < _list_->count; i++) - _list_->f_val->free(_list_->buffer[i]); - } - memset(_list_->buffer, 0, sizeof(size_t) * _list_->capacity); - _list_->count = 0; - _list_->flag = CMC_FLAG_OK; -} -void sl_free(struct sortedlist *_list_) -{ - if (_list_->f_val->free) - { - for (size_t i = 0; i < _list_->count; i++) - _list_->f_val->free(_list_->buffer[i]); - } - _list_->alloc->free(_list_->buffer); - _list_->alloc->free(_list_); -} -void sl_customize(struct sortedlist *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (!alloc) - _list_->alloc = &cmc_alloc_node_default; - else - _list_->alloc = alloc; - (_list_)->callbacks = callbacks; - _list_->flag = CMC_FLAG_OK; -} -_Bool sl_insert(struct sortedlist *_list_, size_t value) -{ - if (sl_full(_list_)) - { - if (!sl_resize(_list_, _list_->capacity * 2)) - return 0; - } - _list_->buffer[_list_->count++] = value; - _list_->is_sorted = 0; - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->create) - (_list_)->callbacks->create(); - ; - return 1; -} -_Bool sl_remove(struct sortedlist *_list_, size_t index) -{ - if (sl_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return 0; - } - if (index >= _list_->count) - { - _list_->flag = CMC_FLAG_RANGE; - return 0; - } - memmove(_list_->buffer + index, _list_->buffer + index + 1, (_list_->count - index) * sizeof(size_t)); - _list_->buffer[--_list_->count] = (size_t){ 0 }; - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->delete) - (_list_)->callbacks->delete (); - ; - return 1; -} -size_t sl_max(struct sortedlist *_list_) -{ - if (sl_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - sl_sort(_list_); - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->read) - (_list_)->callbacks->read(); - ; - return _list_->buffer[_list_->count - 1]; -} -size_t sl_min(struct sortedlist *_list_) -{ - if (sl_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - sl_sort(_list_); - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->read) - (_list_)->callbacks->read(); - ; - return _list_->buffer[0]; -} -size_t sl_get(struct sortedlist *_list_, size_t index) -{ - if (sl_empty(_list_)) - { - _list_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - if (index >= _list_->count) - { - _list_->flag = CMC_FLAG_RANGE; - return (size_t){ 0 }; - } - sl_sort(_list_); - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->read) - (_list_)->callbacks->read(); - ; - return _list_->buffer[index]; -} -size_t sl_index_of(struct sortedlist *_list_, size_t value, _Bool from_start) -{ - _list_->flag = CMC_FLAG_OK; - sl_sort(_list_); - if ((_list_)->callbacks && (_list_)->callbacks->read) - (_list_)->callbacks->read(); - ; - if (from_start) - { - return sl_impl_binary_search_first(_list_, value); - } - return sl_impl_binary_search_last(_list_, value); -} -_Bool sl_contains(struct sortedlist *_list_, size_t value) -{ - _list_->flag = CMC_FLAG_OK; - if (sl_empty(_list_)) - return 0; - sl_sort(_list_); - if ((_list_)->callbacks && (_list_)->callbacks->read) - (_list_)->callbacks->read(); - ; - return sl_impl_binary_search_first(_list_, value) < _list_->count; -} -_Bool sl_empty(struct sortedlist *_list_) -{ - return _list_->count == 0; -} -_Bool sl_full(struct sortedlist *_list_) -{ - return _list_->count >= _list_->capacity; -} -size_t sl_count(struct sortedlist *_list_) -{ - return _list_->count; -} -size_t sl_capacity(struct sortedlist *_list_) -{ - return _list_->capacity; -} -int sl_flag(struct sortedlist *_list_) -{ - return _list_->flag; -} -_Bool sl_resize(struct sortedlist *_list_, size_t capacity) -{ - if (_list_->capacity == capacity) - goto success; - if (capacity < _list_->count) - { - _list_->flag = CMC_FLAG_INVALID; - return 0; - } - size_t *new_buffer = _list_->alloc->realloc(_list_->buffer, sizeof(size_t) * capacity); - if (!new_buffer) - { - _list_->flag = CMC_FLAG_ALLOC; - return 0; - } - _list_->buffer = new_buffer; - _list_->capacity = capacity; -success: - _list_->flag = CMC_FLAG_OK; - if ((_list_)->callbacks && (_list_)->callbacks->resize) - (_list_)->callbacks->resize(); - ; - return 1; -} -void sl_sort(struct sortedlist *_list_) -{ - _list_->flag = CMC_FLAG_OK; - if (!_list_->is_sorted && _list_->count > 1) - { - sl_impl_sort_quicksort(_list_->buffer, _list_->f_val->cmp, 0, _list_->count - 1); - _list_->is_sorted = 1; - } -} -struct sortedlist *sl_copy_of(struct sortedlist *_list_) -{ - struct sortedlist *result = sl_new_custom(_list_->capacity, _list_->f_val, _list_->alloc, ((void *)0)); - if (!result) - { - _list_->flag = CMC_FLAG_ERROR; - return ((void *)0); - } - (result)->callbacks = _list_->callbacks; - if (_list_->f_val->cpy) - { - for (size_t i = 0; i < _list_->count; i++) - result->buffer[i] = _list_->f_val->cpy(_list_->buffer[i]); - } - else - memcpy(result->buffer, _list_->buffer, sizeof(size_t) * _list_->count); - result->count = _list_->count; - _list_->flag = CMC_FLAG_OK; - return result; -} -_Bool sl_equals(struct sortedlist *_list1_, struct sortedlist *_list2_) -{ - if (_list1_->count != _list2_->count) - return 0; - sl_sort(_list1_); - sl_sort(_list2_); - for (size_t i = 0; i < _list1_->count; i++) - { - if (_list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i]) != 0) - return 0; - } - return 1; -} -static size_t sl_impl_binary_search_first(struct sortedlist *_list_, size_t value) -{ - if (sl_empty(_list_)) - return 1; - size_t L = 0; - size_t R = _list_->count; - while (L < R) - { - size_t M = L + (R - L) / 2; - if (_list_->f_val->cmp(_list_->buffer[M], value) < 0) - L = M + 1; - else - R = M; - } - if (_list_->f_val->cmp(_list_->buffer[L], value) == 0) - return L; - return _list_->count; -} -static size_t sl_impl_binary_search_last(struct sortedlist *_list_, size_t value) -{ - if (sl_empty(_list_)) - return 1; - size_t L = 0; - size_t R = _list_->count; - while (L < R) - { - size_t M = L + (R - L) / 2; - if (_list_->f_val->cmp(_list_->buffer[M], value) > 0) - R = M; - else - L = M + 1; - } - if (L > 0 && _list_->f_val->cmp(_list_->buffer[L - 1], value) == 0) - return L - 1; - return _list_->count; -} -void sl_impl_sort_quicksort(size_t *array, int (*cmp)(size_t, size_t), size_t low, size_t high) -{ - while (low < high) - { - if (high - low < 10) - { - sl_impl_sort_insertion(array, cmp, low, high); - break; - } - else - { - size_t pivot = array[high]; - size_t pindex = low; - for (size_t i = low; i < high; i++) - { - if (cmp(array[i], pivot) <= 0) - { - size_t _tmp_ = array[i]; - array[i] = array[pindex]; - array[pindex] = _tmp_; - pindex++; - } - } - size_t _tmp_ = array[pindex]; - array[pindex] = array[high]; - array[high] = _tmp_; - if (pindex - low < high - pindex) - { - sl_impl_sort_quicksort(array, cmp, low, pindex - 1); - low = pindex + 1; - } - else - { - sl_impl_sort_quicksort(array, cmp, pindex + 1, high); - high = pindex - 1; - } - } - } -} -void sl_impl_sort_insertion(size_t *array, int (*cmp)(size_t, size_t), size_t low, size_t high) -{ - for (size_t i = low + 1; i <= high; i++) - { - size_t _tmp_ = array[i]; - size_t j = i; - while (j > low && cmp(array[j - 1], _tmp_) > 0) - { - array[j] = array[j - 1]; - j--; - } - array[j] = _tmp_; - } -} -struct sortedlist_iter sl_iter_start(struct sortedlist *target) -{ - sl_sort(target); - struct sortedlist_iter iter; - iter.target = target; - iter.cursor = 0; - iter.start = 1; - iter.end = sl_empty(target); - return iter; -} -struct sortedlist_iter sl_iter_end(struct sortedlist *target) -{ - sl_sort(target); - struct sortedlist_iter iter; - iter.target = target; - iter.cursor = 0; - iter.start = sl_empty(target); - iter.end = 1; - if (!sl_empty(target)) - iter.cursor = target->count - 1; - return iter; -} -_Bool sl_iter_at_start(struct sortedlist_iter *iter) -{ - return sl_empty(iter->target) || iter->start; -} -_Bool sl_iter_at_end(struct sortedlist_iter *iter) -{ - return sl_empty(iter->target) || iter->end; -} -_Bool sl_iter_to_start(struct sortedlist_iter *iter) -{ - if (!sl_empty(iter->target)) - { - iter->cursor = 0; - iter->start = 1; - iter->end = sl_empty(iter->target); - return 1; - } - return 0; -} -_Bool sl_iter_to_end(struct sortedlist_iter *iter) -{ - if (!sl_empty(iter->target)) - { - iter->start = sl_empty(iter->target); - iter->cursor = iter->target->count - 1; - iter->end = 1; - return 1; - } - return 0; -} -_Bool sl_iter_next(struct sortedlist_iter *iter) -{ - if (iter->end) - return 0; - if (iter->cursor + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - iter->start = sl_empty(iter->target); - iter->cursor++; - return 1; -} -_Bool sl_iter_prev(struct sortedlist_iter *iter) -{ - if (iter->start) - return 0; - if (iter->cursor == 0) - { - iter->start = 1; - return 0; - } - iter->end = sl_empty(iter->target); - iter->cursor--; - return 1; -} -_Bool sl_iter_advance(struct sortedlist_iter *iter, size_t steps) -{ - if (iter->end) - return 0; - if (iter->cursor + 1 == iter->target->count) - { - iter->end = 1; - return 0; - } - if (steps == 0 || iter->cursor + steps >= iter->target->count) - return 0; - iter->start = sl_empty(iter->target); - iter->cursor += steps; - return 1; -} -_Bool sl_iter_rewind(struct sortedlist_iter *iter, size_t steps) -{ - if (iter->start) - return 0; - if (iter->cursor == 0) - { - iter->start = 1; - return 0; - } - if (steps == 0 || iter->cursor < steps) - return 0; - iter->end = sl_empty(iter->target); - iter->cursor -= steps; - return 1; -} -_Bool sl_iter_go_to(struct sortedlist_iter *iter, size_t index) -{ - if (index >= iter->target->count) - return 0; - if (iter->cursor > index) - return sl_iter_rewind(iter, iter->cursor - index); - else if (iter->cursor < index) - return sl_iter_advance(iter, index - iter->cursor); - return 1; -} -size_t sl_iter_value(struct sortedlist_iter *iter) -{ - if (sl_empty(iter->target)) - return (size_t){ 0 }; - return iter->target->buffer[iter->cursor]; -} -size_t sl_iter_index(struct sortedlist_iter *iter) -{ - return iter->cursor; -} -_Bool sl_to_string(struct sortedlist *_list_, FILE *fptr) -{ - struct sortedlist *l_ = _list_; - return 0 <= fprintf(fptr, - "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" - "I64u" - ", " - "count:%" - "I64u" - ", " - "is_sorted:%s, " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }", - "sortedlist", "size_t", l_, l_->buffer, l_->capacity, l_->count, - l_->is_sorted ? "true" : "false", l_->flag, l_->f_val, l_->alloc, (l_)->callbacks); -} -_Bool sl_print(struct sortedlist *_list_, FILE *fptr, const char *start, const char *separator, const char *end) -{ - sl_sort(_list_); - fprintf(fptr, "%s", start); - for (size_t i = 0; i < _list_->count; i++) - { - if (!_list_->f_val->str(fptr, _list_->buffer[i])) - return 0; - if (i + 1 < _list_->count) - fprintf(fptr, "%s", separator); - } - fprintf(fptr, "%s", end); - return 1; -} diff --git a/tests/src/tst_cmc_stack.c b/tests/src/tst_cmc_stack.c deleted file mode 100644 index e6030a3..0000000 --- a/tests/src/tst_cmc_stack.c +++ /dev/null @@ -1,367 +0,0 @@ - -#include "tst_cmc_stack.h" - -struct stack *s_new(size_t capacity, struct stack_fval *f_val) -{ - return s_new_custom(capacity, f_val, ((void *)0), ((void *)0)); -} -struct stack *s_new_custom(size_t capacity, struct stack_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) -{ - ; - if (capacity < 1) - return ((void *)0); - if (!f_val) - return ((void *)0); - if (!alloc) - alloc = &cmc_alloc_node_default; - struct stack *_stack_ = alloc->malloc(sizeof(struct stack)); - if (!_stack_) - return ((void *)0); - _stack_->buffer = alloc->calloc(capacity, sizeof(size_t)); - if (!_stack_->buffer) - { - alloc->free(_stack_); - return ((void *)0); - } - _stack_->capacity = capacity; - _stack_->count = 0; - _stack_->flag = CMC_FLAG_OK; - _stack_->f_val = f_val; - _stack_->alloc = alloc; - (_stack_)->callbacks = callbacks; - return _stack_; -} -void s_clear(struct stack *_stack_) -{ - if (_stack_->f_val->free) - { - for (size_t i = 0; i < _stack_->count; i++) - _stack_->f_val->free(_stack_->buffer[i]); - } - memset(_stack_->buffer, 0, sizeof(size_t) * _stack_->capacity); - _stack_->count = 0; - _stack_->flag = CMC_FLAG_OK; -} -void s_free(struct stack *_stack_) -{ - if (_stack_->f_val->free) - { - for (size_t i = 0; i < _stack_->count; i++) - _stack_->f_val->free(_stack_->buffer[i]); - } - _stack_->alloc->free(_stack_->buffer); - _stack_->alloc->free(_stack_); -} -void s_customize(struct stack *_stack_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (!alloc) - _stack_->alloc = &cmc_alloc_node_default; - else - _stack_->alloc = alloc; - (_stack_)->callbacks = callbacks; - _stack_->flag = CMC_FLAG_OK; -} -_Bool s_push(struct stack *_stack_, size_t value) -{ - if (s_full(_stack_)) - { - if (!s_resize(_stack_, _stack_->capacity * 2)) - return 0; - } - _stack_->buffer[_stack_->count++] = value; - _stack_->flag = CMC_FLAG_OK; - if ((_stack_)->callbacks && (_stack_)->callbacks->create) - (_stack_)->callbacks->create(); - ; - return 1; -} -_Bool s_pop(struct stack *_stack_) -{ - if (s_empty(_stack_)) - { - _stack_->flag = CMC_FLAG_EMPTY; - return 0; - } - _stack_->buffer[--_stack_->count] = (size_t){ 0 }; - _stack_->flag = CMC_FLAG_OK; - if ((_stack_)->callbacks && (_stack_)->callbacks->delete) - (_stack_)->callbacks->delete (); - ; - return 1; -} -size_t s_top(struct stack *_stack_) -{ - if (s_empty(_stack_)) - { - _stack_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - _stack_->flag = CMC_FLAG_OK; - if ((_stack_)->callbacks && (_stack_)->callbacks->read) - (_stack_)->callbacks->read(); - ; - return _stack_->buffer[_stack_->count - 1]; -} -_Bool s_contains(struct stack *_stack_, size_t value) -{ - _stack_->flag = CMC_FLAG_OK; - _Bool result = 0; - for (size_t i = 0; i < _stack_->count; i++) - { - if (_stack_->f_val->cmp(_stack_->buffer[i], value) == 0) - { - result = 1; - break; - } - } - if ((_stack_)->callbacks && (_stack_)->callbacks->read) - (_stack_)->callbacks->read(); - ; - return result; -} -_Bool s_empty(struct stack *_stack_) -{ - return _stack_->count == 0; -} -_Bool s_full(struct stack *_stack_) -{ - return _stack_->count >= _stack_->capacity; -} -size_t s_count(struct stack *_stack_) -{ - return _stack_->count; -} -size_t s_capacity(struct stack *_stack_) -{ - return _stack_->capacity; -} -int s_flag(struct stack *_stack_) -{ - return _stack_->flag; -} -_Bool s_resize(struct stack *_stack_, size_t capacity) -{ - if (_stack_->capacity == capacity) - goto success; - if (capacity < _stack_->count) - { - _stack_->flag = CMC_FLAG_INVALID; - return 0; - } - size_t *new_buffer = _stack_->alloc->realloc(_stack_->buffer, sizeof(size_t) * capacity); - if (!new_buffer) - { - _stack_->flag = CMC_FLAG_ALLOC; - return 0; - } - _stack_->buffer = new_buffer; - _stack_->capacity = capacity; -success: - _stack_->flag = CMC_FLAG_OK; - if ((_stack_)->callbacks && (_stack_)->callbacks->resize) - (_stack_)->callbacks->resize(); - ; - return 1; -} -struct stack *s_copy_of(struct stack *_stack_) -{ - struct stack *result = s_new_custom(_stack_->capacity, _stack_->f_val, _stack_->alloc, ((void *)0)); - if (!result) - { - _stack_->flag = CMC_FLAG_ERROR; - return ((void *)0); - } - (result)->callbacks = _stack_->callbacks; - if (_stack_->f_val->cpy) - { - for (size_t i = 0; i < _stack_->count; i++) - result->buffer[i] = _stack_->f_val->cpy(_stack_->buffer[i]); - } - else - memcpy(result->buffer, _stack_->buffer, sizeof(size_t) * _stack_->count); - result->count = _stack_->count; - _stack_->flag = CMC_FLAG_OK; - return result; -} -_Bool s_equals(struct stack *_stack1_, struct stack *_stack2_) -{ - _stack1_->flag = CMC_FLAG_OK; - _stack2_->flag = CMC_FLAG_OK; - if (_stack1_->count != _stack2_->count) - return 0; - for (size_t i = 0; i < _stack1_->count; i++) - { - if (_stack1_->f_val->cmp(_stack1_->buffer[i], _stack2_->buffer[i]) != 0) - return 0; - } - return 1; -} -struct stack_iter s_iter_start(struct stack *target) -{ - struct stack_iter iter; - iter.target = target; - iter.cursor = 0; - iter.start = 1; - iter.end = s_empty(target); - if (!s_empty(target)) - iter.cursor = target->count - 1; - return iter; -} -struct stack_iter s_iter_end(struct stack *target) -{ - struct stack_iter iter; - iter.target = target; - iter.cursor = 0; - iter.start = s_empty(target); - iter.end = 1; - return iter; -} -_Bool s_iter_at_start(struct stack_iter *iter) -{ - return s_empty(iter->target) || iter->start; -} -_Bool s_iter_at_end(struct stack_iter *iter) -{ - return s_empty(iter->target) || iter->end; -} -_Bool s_iter_to_start(struct stack_iter *iter) -{ - if (!s_empty(iter->target)) - { - iter->cursor = iter->target->count - 1; - iter->start = 1; - iter->end = s_empty(iter->target); - return 1; - } - return 0; -} -_Bool s_iter_to_end(struct stack_iter *iter) -{ - if (!s_empty(iter->target)) - { - iter->cursor = 0; - iter->start = s_empty(iter->target); - iter->end = 1; - return 1; - } - return 0; -} -_Bool s_iter_next(struct stack_iter *iter) -{ - if (iter->end) - return 0; - if (iter->cursor == 0) - { - iter->end = 1; - return 0; - } - iter->start = s_empty(iter->target); - iter->cursor--; - return 1; -} -_Bool s_iter_prev(struct stack_iter *iter) -{ - if (iter->start) - return 0; - if (iter->cursor + 1 == iter->target->count) - { - iter->start = 1; - return 0; - } - iter->end = s_empty(iter->target); - iter->cursor++; - return 1; -} -_Bool s_iter_advance(struct stack_iter *iter, size_t steps) -{ - if (iter->end) - return 0; - if (iter->cursor == 0) - { - iter->end = 1; - return 0; - } - if (steps == 0 || iter->cursor < steps) - return 0; - iter->start = s_empty(iter->target); - iter->cursor -= steps; - return 1; -} -_Bool s_iter_rewind(struct stack_iter *iter, size_t steps) -{ - if (iter->start) - return 0; - if (iter->cursor + 1 == iter->target->count) - { - iter->start = 1; - return 0; - } - if (steps == 0 || iter->cursor + steps >= iter->target->count) - return 0; - iter->end = s_empty(iter->target); - iter->cursor += steps; - return 1; -} -_Bool s_iter_go_to(struct stack_iter *iter, size_t index) -{ - if (index >= iter->target->count) - return 0; - if (iter->cursor > index) - return s_iter_advance(iter, iter->cursor - index); - else if (iter->cursor < index) - return s_iter_rewind(iter, index - iter->cursor); - return 1; -} -size_t s_iter_value(struct stack_iter *iter) -{ - if (s_empty(iter->target)) - return (size_t){ 0 }; - return iter->target->buffer[iter->cursor]; -} -size_t *s_iter_rvalue(struct stack_iter *iter) -{ - if (s_empty(iter->target)) - return ((void *)0); - return &(iter->target->buffer[iter->cursor]); -} -size_t s_iter_index(struct stack_iter *iter) -{ - if (s_empty(iter->target)) - return 0; - return iter->target->count - 1 - iter->cursor; -} -_Bool s_to_string(struct stack *_stack_, FILE *fptr) -{ - struct stack *s_ = _stack_; - return 0 <= fprintf(fptr, - "struct %s<%s> " - "at %p { " - "buffer:%p, " - "capacity:%" - "I64u" - ", " - "count:%" - "I64u" - ", " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }", - "stack", "size_t", s_, s_->buffer, s_->capacity, s_->count, s_->flag, s_->f_val, s_->alloc, - (s_)->callbacks); -} -_Bool s_print(struct stack *_stack_, FILE *fptr, const char *start, const char *separator, const char *end) -{ - fprintf(fptr, "%s", start); - for (size_t i = _stack_->count; i > 0; i--) - { - if (!_stack_->f_val->str(fptr, _stack_->buffer[i - 1])) - return 0; - if (i - 1 != 0) - fprintf(fptr, "%s", separator); - } - fprintf(fptr, "%s", end); - return 1; -} diff --git a/tests/src/tst_cmc_treemap.c b/tests/src/tst_cmc_treemap.c deleted file mode 100644 index ed28e22..0000000 --- a/tests/src/tst_cmc_treemap.c +++ /dev/null @@ -1,852 +0,0 @@ - -#include "tst_cmc_treemap.h" - -static struct treemap_node *tm_impl_new_node(struct treemap *_map_, size_t key, size_t value); -static struct treemap_node *tm_impl_get_node(struct treemap *_map_, size_t key); -static unsigned char tm_impl_h(struct treemap_node *node); -static unsigned char tm_impl_hupdate(struct treemap_node *node); -static void tm_impl_rotate_right(struct treemap_node **Z); -static void tm_impl_rotate_left(struct treemap_node **Z); -static void tm_impl_rebalance(struct treemap *_map_, struct treemap_node *node); -struct treemap *tm_new(struct treemap_fkey *f_key, struct treemap_fval *f_val) -{ - return tm_new_custom(f_key, f_val, ((void *)0), ((void *)0)); -} -struct treemap *tm_new_custom(struct treemap_fkey *f_key, struct treemap_fval *f_val, struct cmc_alloc_node *alloc, - struct cmc_callbacks *callbacks) -{ - ; - if (!f_key || !f_val) - return ((void *)0); - if (!alloc) - alloc = &cmc_alloc_node_default; - struct treemap *_map_ = alloc->malloc(sizeof(struct treemap)); - if (!_map_) - return ((void *)0); - _map_->count = 0; - _map_->root = ((void *)0); - _map_->flag = CMC_FLAG_OK; - _map_->f_key = f_key; - _map_->f_val = f_val; - _map_->alloc = alloc; - (_map_)->callbacks = callbacks; - return _map_; -} -void tm_clear(struct treemap *_map_) -{ - struct treemap_node *scan = _map_->root; - struct treemap_node *up = ((void *)0); - while (scan != ((void *)0)) - { - if (scan->left != ((void *)0)) - { - struct treemap_node *left = scan->left; - scan->left = up; - up = scan; - scan = left; - } - else if (scan->right != ((void *)0)) - { - struct treemap_node *right = scan->right; - scan->left = up; - scan->right = ((void *)0); - up = scan; - scan = right; - } - else - { - if (up == ((void *)0)) - { - if (_map_->f_key->free) - _map_->f_key->free(scan->key); - if (_map_->f_val->free) - _map_->f_val->free(scan->value); - _map_->alloc->free(scan); - scan = ((void *)0); - } - while (up != ((void *)0)) - { - if (_map_->f_key->free) - _map_->f_key->free(scan->key); - if (_map_->f_val->free) - _map_->f_val->free(scan->value); - _map_->alloc->free(scan); - if (up->right != ((void *)0)) - { - scan = up->right; - up->right = ((void *)0); - break; - } - else - { - scan = up; - up = up->left; - } - } - } - } - _map_->count = 0; - _map_->root = ((void *)0); - _map_->flag = CMC_FLAG_OK; -} -void tm_free(struct treemap *_map_) -{ - tm_clear(_map_); - _map_->alloc->free(_map_); -} -void tm_customize(struct treemap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (!alloc) - _map_->alloc = &cmc_alloc_node_default; - else - _map_->alloc = alloc; - (_map_)->callbacks = callbacks; - _map_->flag = CMC_FLAG_OK; -} -_Bool tm_insert(struct treemap *_map_, size_t key, size_t value) -{ - if (tm_empty(_map_)) - { - _map_->root = tm_impl_new_node(_map_, key, value); - if (!_map_->root) - { - _map_->flag = CMC_FLAG_ALLOC; - return 0; - } - } - else - { - struct treemap_node *scan = _map_->root; - struct treemap_node *parent = scan; - while (scan != ((void *)0)) - { - parent = scan; - if (_map_->f_key->cmp(scan->key, key) > 0) - scan = scan->left; - else if (_map_->f_key->cmp(scan->key, key) < 0) - scan = scan->right; - else - { - _map_->flag = CMC_FLAG_DUPLICATE; - return 0; - } - } - struct treemap_node *node; - if (_map_->f_key->cmp(parent->key, key) > 0) - { - parent->left = tm_impl_new_node(_map_, key, value); - if (!parent->left) - { - _map_->flag = CMC_FLAG_ALLOC; - return 0; - } - parent->left->parent = parent; - node = parent->left; - } - else - { - parent->right = tm_impl_new_node(_map_, key, value); - if (!parent->right) - { - _map_->flag = CMC_FLAG_ALLOC; - return 0; - } - parent->right->parent = parent; - node = parent->right; - } - tm_impl_rebalance(_map_, node); - } - _map_->count++; - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->create) - (_map_)->callbacks->create(); - ; - return 1; -} -_Bool tm_update(struct treemap *_map_, size_t key, size_t new_value, size_t *old_value) -{ - struct treemap_node *node = tm_impl_get_node(_map_, key); - if (!node) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - if (old_value) - *old_value = node->value; - node->value = new_value; - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->update) - (_map_)->callbacks->update(); - ; - return 1; -} -_Bool tm_remove(struct treemap *_map_, size_t key, size_t *out_value) -{ - if (tm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct treemap_node *node = tm_impl_get_node(_map_, key); - if (!node) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - if (out_value) - *out_value = node->value; - struct treemap_node *temp = ((void *)0), *unbalanced = ((void *)0); - _Bool is_root = node->parent == ((void *)0); - if (node->left == ((void *)0) && node->right == ((void *)0)) - { - if (is_root) - _map_->root = ((void *)0); - else - { - unbalanced = node->parent; - if (node->parent->right == node) - node->parent->right = ((void *)0); - else - node->parent->left = ((void *)0); - } - _map_->alloc->free(node); - } - else if (node->left == ((void *)0)) - { - if (is_root) - { - _map_->root = node->right; - _map_->root->parent = ((void *)0); - } - else - { - unbalanced = node->parent; - node->right->parent = node->parent; - if (node->parent->right == node) - node->parent->right = node->right; - else - node->parent->left = node->right; - } - _map_->alloc->free(node); - } - else if (node->right == ((void *)0)) - { - if (is_root) - { - _map_->root = node->left; - _map_->root->parent = ((void *)0); - } - else - { - unbalanced = node->parent; - node->left->parent = node->parent; - if (node->parent->right == node) - node->parent->right = node->left; - else - node->parent->left = node->left; - } - _map_->alloc->free(node); - } - else - { - temp = node->right; - while (temp->left != ((void *)0)) - temp = temp->left; - size_t temp_key = temp->key; - size_t temp_val = temp->value; - unbalanced = temp->parent; - if (temp->left == ((void *)0) && temp->right == ((void *)0)) - { - if (temp->parent->right == temp) - temp->parent->right = ((void *)0); - else - temp->parent->left = ((void *)0); - } - else if (temp->left == ((void *)0)) - { - temp->right->parent = temp->parent; - if (temp->parent->right == temp) - temp->parent->right = temp->right; - else - temp->parent->left = temp->right; - } - else if (temp->right == ((void *)0)) - { - temp->left->parent = temp->parent; - if (temp->parent->right == temp) - temp->parent->right = temp->left; - else - temp->parent->left = temp->left; - } - _map_->alloc->free(temp); - node->key = temp_key; - node->value = temp_val; - } - if (unbalanced != ((void *)0)) - tm_impl_rebalance(_map_, unbalanced); - if (_map_->count == 0) - _map_->root = ((void *)0); - _map_->count--; - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->delete) - (_map_)->callbacks->delete (); - ; - return 1; -} -_Bool tm_max(struct treemap *_map_, size_t *key, size_t *value) -{ - if (tm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct treemap_node *scan = _map_->root; - while (scan->right != ((void *)0)) - scan = scan->right; - if (key) - *key = scan->key; - if (value) - *value = scan->value; - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->read) - (_map_)->callbacks->read(); - ; - return 1; -} -_Bool tm_min(struct treemap *_map_, size_t *key, size_t *value) -{ - if (tm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct treemap_node *scan = _map_->root; - while (scan->left != ((void *)0)) - scan = scan->left; - if (key) - *key = scan->key; - if (value) - *value = scan->value; - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->read) - (_map_)->callbacks->read(); - ; - return 1; -} -size_t tm_get(struct treemap *_map_, size_t key) -{ - if (tm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return (size_t){ 0 }; - } - struct treemap_node *node = tm_impl_get_node(_map_, key); - if (!node) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return (size_t){ 0 }; - } - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->read) - (_map_)->callbacks->read(); - ; - return node->value; -} -size_t *tm_get_ref(struct treemap *_map_, size_t key) -{ - if (tm_empty(_map_)) - { - _map_->flag = CMC_FLAG_EMPTY; - return ((void *)0); - } - struct treemap_node *node = tm_impl_get_node(_map_, key); - if (!node) - { - _map_->flag = CMC_FLAG_NOT_FOUND; - return ((void *)0); - } - _map_->flag = CMC_FLAG_OK; - if ((_map_)->callbacks && (_map_)->callbacks->read) - (_map_)->callbacks->read(); - ; - return &(node->value); -} -_Bool tm_contains(struct treemap *_map_, size_t key) -{ - _Bool result = tm_impl_get_node(_map_, key) != ((void *)0); - if ((_map_)->callbacks && (_map_)->callbacks->read) - (_map_)->callbacks->read(); - ; - return result; -} -_Bool tm_empty(struct treemap *_map_) -{ - return _map_->count == 0; -} -size_t tm_count(struct treemap *_map_) -{ - return _map_->count; -} -int tm_flag(struct treemap *_map_) -{ - return _map_->flag; -} -struct treemap *tm_copy_of(struct treemap *_map_) -{ - struct treemap *result = tm_new_custom(_map_->f_key, _map_->f_val, _map_->alloc, ((void *)0)); - if (!result) - { - _map_->flag = CMC_FLAG_ERROR; - return ((void *)0); - } - struct treemap_node *root = _map_->root; - _Bool left_done = 0; - while (root) - { - if (!left_done) - { - while (root->left) - root = root->left; - } - size_t key; - size_t value; - if (_map_->f_key->cpy) - key = _map_->f_key->cpy(root->key); - else - key = root->key; - if (_map_->f_val->cpy) - value = _map_->f_val->cpy(root->value); - else - value = root->value; - tm_insert(result, key, value); - left_done = 1; - if (root->right) - { - left_done = 0; - root = root->right; - } - else if (root->parent) - { - while (root->parent && root == root->parent->right) - root = root->parent; - if (!root->parent) - break; - root = root->parent; - } - else - break; - } - _map_->flag = CMC_FLAG_OK; - (result)->callbacks = _map_->callbacks; - return result; -} -_Bool tm_equals(struct treemap *_map1_, struct treemap *_map2_) -{ - _map1_->flag = CMC_FLAG_OK; - _map2_->flag = CMC_FLAG_OK; - if (_map1_->count != _map2_->count) - return 0; - struct treemap_node *root = _map1_->root; - _Bool left_done = 0; - while (root) - { - if (!left_done) - { - while (root->left) - root = root->left; - } - struct treemap_node *node = tm_impl_get_node(_map2_, root->key); - if (node == ((void *)0)) - return 0; - if (_map1_->f_val->cmp(node->value, root->value) != 0) - return 0; - left_done = 1; - if (root->right) - { - left_done = 0; - root = root->right; - } - else if (root->parent) - { - while (root->parent && root == root->parent->right) - root = root->parent; - if (!root->parent) - break; - root = root->parent; - } - else - break; - } - return 1; -} -static struct treemap_node *tm_impl_new_node(struct treemap *_map_, size_t key, size_t value) -{ - struct treemap_node *node = _map_->alloc->malloc(sizeof(struct treemap_node)); - if (!node) - return ((void *)0); - node->key = key; - node->value = value; - node->right = ((void *)0); - node->left = ((void *)0); - node->parent = ((void *)0); - node->height = 0; - return node; -} -static struct treemap_node *tm_impl_get_node(struct treemap *_map_, size_t key) -{ - struct treemap_node *scan = _map_->root; - while (scan != ((void *)0)) - { - if (_map_->f_key->cmp(scan->key, key) > 0) - scan = scan->left; - else if (_map_->f_key->cmp(scan->key, key) < 0) - scan = scan->right; - else - return scan; - } - return ((void *)0); -} -static unsigned char tm_impl_h(struct treemap_node *node) -{ - if (node == ((void *)0)) - return 0; - return node->height; -} -static unsigned char tm_impl_hupdate(struct treemap_node *node) -{ - if (node == ((void *)0)) - return 0; - unsigned char h_l = tm_impl_h(node->left); - unsigned char h_r = tm_impl_h(node->right); - return 1 + (h_l > h_r ? h_l : h_r); -} -static void tm_impl_rotate_right(struct treemap_node **Z) -{ - struct treemap_node *root = *Z; - struct treemap_node *new_root = root->left; - if (root->parent != ((void *)0)) - { - if (root->parent->left == root) - root->parent->left = new_root; - else - root->parent->right = new_root; - } - new_root->parent = root->parent; - root->parent = new_root; - root->left = new_root->right; - if (root->left) - root->left->parent = root; - new_root->right = root; - root->height = tm_impl_hupdate(root); - new_root->height = tm_impl_hupdate(new_root); - *Z = new_root; -} -static void tm_impl_rotate_left(struct treemap_node **Z) -{ - struct treemap_node *root = *Z; - struct treemap_node *new_root = root->right; - if (root->parent != ((void *)0)) - { - if (root->parent->right == root) - root->parent->right = new_root; - else - root->parent->left = new_root; - } - new_root->parent = root->parent; - root->parent = new_root; - root->right = new_root->left; - if (root->right) - root->right->parent = root; - new_root->left = root; - root->height = tm_impl_hupdate(root); - new_root->height = tm_impl_hupdate(new_root); - *Z = new_root; -} -static void tm_impl_rebalance(struct treemap *_map_, struct treemap_node *node) -{ - struct treemap_node *scan = node, *child = ((void *)0); - int balance; - _Bool is_root = 0; - while (scan != ((void *)0)) - { - if (scan->parent == ((void *)0)) - is_root = 1; - scan->height = tm_impl_hupdate(scan); - balance = tm_impl_h(scan->right) - tm_impl_h(scan->left); - if (balance >= 2) - { - child = scan->right; - if (tm_impl_h(child->right) < tm_impl_h(child->left)) - tm_impl_rotate_right(&(scan->right)); - tm_impl_rotate_left(&scan); - } - else if (balance <= -2) - { - child = scan->left; - if (tm_impl_h(child->left) < tm_impl_h(child->right)) - tm_impl_rotate_left(&(scan->left)); - tm_impl_rotate_right(&scan); - } - if (is_root) - { - _map_->root = scan; - is_root = 0; - } - scan = scan->parent; - } -} -struct treemap_iter tm_iter_start(struct treemap *target) -{ - struct treemap_iter iter; - iter.target = target; - iter.cursor = target->root; - iter.first = ((void *)0); - iter.last = ((void *)0); - iter.index = 0; - iter.start = 1; - iter.end = tm_empty(target); - if (!tm_empty(target)) - { - while (iter.cursor->left != ((void *)0)) - iter.cursor = iter.cursor->left; - iter.first = iter.cursor; - iter.last = target->root; - while (iter.last->right != ((void *)0)) - iter.last = iter.last->right; - } - return iter; -} -struct treemap_iter tm_iter_end(struct treemap *target) -{ - struct treemap_iter iter; - iter.target = target; - iter.cursor = target->root; - iter.first = ((void *)0); - iter.last = ((void *)0); - iter.index = 0; - iter.start = tm_empty(target); - iter.end = 1; - if (!tm_empty(target)) - { - while (iter.cursor->right != ((void *)0)) - iter.cursor = iter.cursor->right; - iter.last = iter.cursor; - iter.first = target->root; - while (iter.first->left != ((void *)0)) - iter.first = iter.first->left; - iter.index = target->count - 1; - } - return iter; -} -_Bool tm_iter_at_start(struct treemap_iter *iter) -{ - return tm_empty(iter->target) || iter->start; -} -_Bool tm_iter_at_end(struct treemap_iter *iter) -{ - return tm_empty(iter->target) || iter->end; -} -_Bool tm_iter_to_start(struct treemap_iter *iter) -{ - if (!tm_empty(iter->target)) - { - iter->index = 0; - iter->start = 1; - iter->end = tm_empty(iter->target); - iter->cursor = iter->first; - return 1; - } - return 0; -} -_Bool tm_iter_to_end(struct treemap_iter *iter) -{ - if (!tm_empty(iter->target)) - { - iter->index = iter->target->count - 1; - iter->start = tm_empty(iter->target); - iter->end = 1; - iter->cursor = iter->last; - return 1; - } - return 0; -} -_Bool tm_iter_next(struct treemap_iter *iter) -{ - if (iter->end) - return 0; - if (iter->cursor == iter->last) - { - iter->end = 1; - return 0; - } - iter->start = tm_empty(iter->target); - if (iter->cursor->right != ((void *)0)) - { - iter->cursor = iter->cursor->right; - while (iter->cursor->left != ((void *)0)) - iter->cursor = iter->cursor->left; - iter->index++; - return 1; - } - while (1) - { - if (iter->cursor->parent->left == iter->cursor) - { - iter->cursor = iter->cursor->parent; - iter->index++; - return 1; - } - iter->cursor = iter->cursor->parent; - } -} -_Bool tm_iter_prev(struct treemap_iter *iter) -{ - if (iter->start) - return 0; - if (iter->cursor == iter->first) - { - iter->start = 1; - return 0; - } - iter->end = tm_empty(iter->target); - if (iter->cursor->left != ((void *)0)) - { - iter->cursor = iter->cursor->left; - while (iter->cursor->right != ((void *)0)) - iter->cursor = iter->cursor->right; - iter->index--; - return 1; - } - while (1) - { - if (iter->cursor->parent->right == iter->cursor) - { - iter->cursor = iter->cursor->parent; - iter->index--; - return 1; - } - iter->cursor = iter->cursor->parent; - } -} -_Bool tm_iter_advance(struct treemap_iter *iter, size_t steps) -{ - if (iter->end) - return 0; - if (iter->cursor == iter->last) - { - iter->end = 1; - return 0; - } - if (steps == 0 || iter->index + steps >= iter->target->count) - return 0; - for (size_t i = 0; i < steps; i++) - tm_iter_next(iter); - return 1; -} -_Bool tm_iter_rewind(struct treemap_iter *iter, size_t steps) -{ - if (iter->start) - return 0; - if (iter->cursor == iter->first) - { - iter->start = 1; - return 0; - } - if (steps == 0 || iter->index < steps) - return 0; - for (size_t i = 0; i < steps; i++) - tm_iter_prev(iter); - return 1; -} -_Bool tm_iter_go_to(struct treemap_iter *iter, size_t index) -{ - if (index >= iter->target->count) - return 0; - if (iter->index > index) - return tm_iter_rewind(iter, iter->index - index); - else if (iter->index < index) - return tm_iter_advance(iter, index - iter->index); - return 1; -} -size_t tm_iter_key(struct treemap_iter *iter) -{ - if (tm_empty(iter->target)) - return (size_t){ 0 }; - return iter->cursor->key; -} -size_t tm_iter_value(struct treemap_iter *iter) -{ - if (tm_empty(iter->target)) - return (size_t){ 0 }; - return iter->cursor->value; -} -size_t *tm_iter_rvalue(struct treemap_iter *iter) -{ - if (tm_empty(iter->target)) - return ((void *)0); - return &(iter->cursor->value); -} -size_t tm_iter_index(struct treemap_iter *iter) -{ - return iter->index; -} -_Bool tm_to_string(struct treemap *_map_, FILE *fptr) -{ - struct treemap *m_ = _map_; - return 0 <= fprintf(fptr, - "struct %s<%s, %s> " - "at %p { " - "root:%p, " - "count:%" - "I64u" - ", " - "flag:%d, " - "f_val:%p, " - "f_key:%p, " - "alloc:%p, " - "callbacks:%p }", - "treemap", "size_t", "size_t", m_, m_->root, m_->count, m_->flag, m_->f_key, m_->f_val, - m_->alloc, (m_)->callbacks); -} -_Bool tm_print(struct treemap *_map_, FILE *fptr, const char *start, const char *separator, const char *end, - const char *key_val_sep) -{ - fprintf(fptr, "%s", start); - struct treemap_node *root = _map_->root; - _Bool left_done = 0; - size_t i = 0; - while (root) - { - if (!left_done) - { - while (root->left) - root = root->left; - } - if (!_map_->f_key->str(fptr, root->key)) - return 0; - fprintf(fptr, "%s", key_val_sep); - if (!_map_->f_val->str(fptr, root->value)) - return 0; - if (++i < _map_->count) - fprintf(fptr, "%s", separator); - left_done = 1; - if (root->right) - { - left_done = 0; - root = root->right; - } - else if (root->parent) - { - while (root->parent && root == root->parent->right) - root = root->parent; - if (!root->parent) - break; - root = root->parent; - } - else - break; - } - fprintf(fptr, "%s", end); - return 1; -} diff --git a/tests/src/tst_cmc_treeset.c b/tests/src/tst_cmc_treeset.c deleted file mode 100644 index b0a60ce..0000000 --- a/tests/src/tst_cmc_treeset.c +++ /dev/null @@ -1,841 +0,0 @@ - -#include "tst_cmc_treeset.h" - -static struct treeset_node *ts_impl_new_node(struct treeset *_set_, size_t value); -static struct treeset_node *ts_impl_get_node(struct treeset *_set_, size_t value); -static unsigned char ts_impl_h(struct treeset_node *node); -static unsigned char ts_impl_hupdate(struct treeset_node *node); -static void ts_impl_rotate_right(struct treeset_node **Z); -static void ts_impl_rotate_left(struct treeset_node **Z); -static void ts_impl_rebalance(struct treeset *_set_, struct treeset_node *node); -struct treeset *ts_new(struct treeset_fval *f_val) -{ - return ts_new_custom(f_val, ((void *)0), ((void *)0)); -} -struct treeset *ts_new_custom(struct treeset_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (!f_val) - return ((void *)0); - if (!alloc) - alloc = &cmc_alloc_node_default; - struct treeset *_set_ = alloc->malloc(sizeof(struct treeset)); - if (!_set_) - return ((void *)0); - _set_->count = 0; - _set_->root = ((void *)0); - _set_->flag = CMC_FLAG_OK; - _set_->f_val = f_val; - _set_->alloc = alloc; - (_set_)->callbacks = callbacks; - return _set_; -} -void ts_clear(struct treeset *_set_) -{ - struct treeset_node *scan = _set_->root; - struct treeset_node *up = ((void *)0); - while (scan != ((void *)0)) - { - if (scan->left != ((void *)0)) - { - struct treeset_node *left = scan->left; - scan->left = up; - up = scan; - scan = left; - } - else if (scan->right != ((void *)0)) - { - struct treeset_node *right = scan->right; - scan->left = up; - scan->right = ((void *)0); - up = scan; - scan = right; - } - else - { - if (up == ((void *)0)) - { - if (_set_->f_val->free) - _set_->f_val->free(scan->value); - _set_->alloc->free(scan); - scan = ((void *)0); - } - while (up != ((void *)0)) - { - if (_set_->f_val->free) - _set_->f_val->free(scan->value); - _set_->alloc->free(scan); - if (up->right != ((void *)0)) - { - scan = up->right; - up->right = ((void *)0); - break; - } - else - { - scan = up; - up = up->left; - } - } - } - } - _set_->count = 0; - _set_->root = ((void *)0); - _set_->flag = CMC_FLAG_OK; -} -void ts_free(struct treeset *_set_) -{ - ts_clear(_set_); - _set_->alloc->free(_set_); -} -void ts_customize(struct treeset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) -{ - ; - if (!alloc) - _set_->alloc = &cmc_alloc_node_default; - else - _set_->alloc = alloc; - (_set_)->callbacks = callbacks; - _set_->flag = CMC_FLAG_OK; -} -_Bool ts_insert(struct treeset *_set_, size_t value) -{ - if (ts_empty(_set_)) - { - _set_->root = ts_impl_new_node(_set_, value); - if (!_set_->root) - { - _set_->flag = CMC_FLAG_ALLOC; - return 0; - } - } - else - { - struct treeset_node *scan = _set_->root; - struct treeset_node *parent = scan; - while (scan != ((void *)0)) - { - parent = scan; - if (_set_->f_val->cmp(scan->value, value) > 0) - scan = scan->left; - else if (_set_->f_val->cmp(scan->value, value) < 0) - scan = scan->right; - else - { - _set_->flag = CMC_FLAG_DUPLICATE; - return 0; - } - } - struct treeset_node *node; - if (_set_->f_val->cmp(parent->value, value) > 0) - { - parent->left = ts_impl_new_node(_set_, value); - if (!parent->left) - { - _set_->flag = CMC_FLAG_ALLOC; - return 0; - } - parent->left->parent = parent; - node = parent->left; - } - else - { - parent->right = ts_impl_new_node(_set_, value); - if (!parent->right) - { - _set_->flag = CMC_FLAG_ALLOC; - return 0; - } - parent->right->parent = parent; - node = parent->right; - } - ts_impl_rebalance(_set_, node); - } - _set_->count++; - _set_->flag = CMC_FLAG_OK; - if ((_set_)->callbacks && (_set_)->callbacks->create) - (_set_)->callbacks->create(); - ; - return 1; -} -_Bool ts_remove(struct treeset *_set_, size_t value) -{ - if (ts_empty(_set_)) - { - _set_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct treeset_node *node = ts_impl_get_node(_set_, value); - if (!node) - { - _set_->flag = CMC_FLAG_NOT_FOUND; - return 0; - } - struct treeset_node *temp = ((void *)0), *unbalanced = ((void *)0); - _Bool is_root = node->parent == ((void *)0); - if (node->left == ((void *)0) && node->right == ((void *)0)) - { - if (is_root) - _set_->root = ((void *)0); - else - { - unbalanced = node->parent; - if (node->parent->right == node) - node->parent->right = ((void *)0); - else - node->parent->left = ((void *)0); - } - _set_->alloc->free(node); - } - else if (node->left == ((void *)0)) - { - if (is_root) - { - _set_->root = node->right; - _set_->root->parent = ((void *)0); - } - else - { - unbalanced = node->parent; - node->right->parent = node->parent; - if (node->parent->right == node) - node->parent->right = node->right; - else - node->parent->left = node->right; - } - _set_->alloc->free(node); - } - else if (node->right == ((void *)0)) - { - if (is_root) - { - _set_->root = node->left; - _set_->root->parent = ((void *)0); - } - else - { - unbalanced = node->parent; - node->left->parent = node->parent; - if (node->parent->right == node) - node->parent->right = node->left; - else - node->parent->left = node->left; - } - _set_->alloc->free(node); - } - else - { - temp = node->right; - while (temp->left != ((void *)0)) - temp = temp->left; - size_t temp_value = temp->value; - unbalanced = temp->parent; - if (temp->left == ((void *)0) && temp->right == ((void *)0)) - { - if (temp->parent->right == temp) - temp->parent->right = ((void *)0); - else - temp->parent->left = ((void *)0); - } - else if (temp->left == ((void *)0)) - { - temp->right->parent = temp->parent; - if (temp->parent->right == temp) - temp->parent->right = temp->right; - else - temp->parent->left = temp->right; - } - else if (temp->right == ((void *)0)) - { - temp->left->parent = temp->parent; - if (temp->parent->right == temp) - temp->parent->right = temp->left; - else - temp->parent->left = temp->left; - } - _set_->alloc->free(temp); - node->value = temp_value; - } - if (unbalanced != ((void *)0)) - ts_impl_rebalance(_set_, unbalanced); - if (_set_->count == 0) - _set_->root = ((void *)0); - _set_->count--; - _set_->flag = CMC_FLAG_OK; - if ((_set_)->callbacks && (_set_)->callbacks->delete) - (_set_)->callbacks->delete (); - ; - return 1; -} -_Bool ts_max(struct treeset *_set_, size_t *value) -{ - if (ts_empty(_set_)) - { - _set_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct treeset_node *scan = _set_->root; - while (scan->right != ((void *)0)) - scan = scan->right; - if (value) - *value = scan->value; - _set_->flag = CMC_FLAG_OK; - if ((_set_)->callbacks && (_set_)->callbacks->read) - (_set_)->callbacks->read(); - ; - return 1; -} -_Bool ts_min(struct treeset *_set_, size_t *value) -{ - if (ts_empty(_set_)) - { - _set_->flag = CMC_FLAG_EMPTY; - return 0; - } - struct treeset_node *scan = _set_->root; - while (scan->left != ((void *)0)) - scan = scan->left; - if (value) - *value = scan->value; - _set_->flag = CMC_FLAG_OK; - if ((_set_)->callbacks && (_set_)->callbacks->read) - (_set_)->callbacks->read(); - ; - return 1; -} -_Bool ts_contains(struct treeset *_set_, size_t value) -{ - _Bool result = ts_impl_get_node(_set_, value) != ((void *)0); - if ((_set_)->callbacks && (_set_)->callbacks->read) - (_set_)->callbacks->read(); - ; - return result; -} -_Bool ts_empty(struct treeset *_set_) -{ - return _set_->count == 0; -} -size_t ts_count(struct treeset *_set_) -{ - return _set_->count; -} -int ts_flag(struct treeset *_set_) -{ - return _set_->flag; -} -struct treeset *ts_copy_of(struct treeset *_set_) -{ - struct treeset *result = ts_new_custom(_set_->f_val, _set_->alloc, ((void *)0)); - if (!result) - { - _set_->flag = CMC_FLAG_ERROR; - return ((void *)0); - } - (result)->callbacks = _set_->callbacks; - if (!ts_empty(_set_)) - { - struct treeset_iter iter = ts_iter_start(_set_); - for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) - { - if (_set_->f_val->cpy) - ts_insert(result, _set_->f_val->cpy(ts_iter_value(&iter))); - else - ts_insert(result, ts_iter_value(&iter)); - } - } - _set_->flag = CMC_FLAG_OK; - return result; -} -_Bool ts_equals(struct treeset *_set1_, struct treeset *_set2_) -{ - _set1_->flag = CMC_FLAG_OK; - _set2_->flag = CMC_FLAG_OK; - if (_set1_->count != _set2_->count) - return 0; - struct treeset_iter iter = ts_iter_start(_set1_); - for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) - { - if (ts_impl_get_node(_set2_, ts_iter_value(&iter)) == ((void *)0)) - return 0; - } - return 1; -} -static struct treeset_node *ts_impl_new_node(struct treeset *_set_, size_t value) -{ - struct treeset_node *node = _set_->alloc->malloc(sizeof(struct treeset_node)); - if (!node) - return ((void *)0); - node->value = value; - node->right = ((void *)0); - node->left = ((void *)0); - node->parent = ((void *)0); - node->height = 0; - return node; -} -static struct treeset_node *ts_impl_get_node(struct treeset *_set_, size_t value) -{ - struct treeset_node *scan = _set_->root; - while (scan != ((void *)0)) - { - if (_set_->f_val->cmp(scan->value, value) > 0) - scan = scan->left; - else if (_set_->f_val->cmp(scan->value, value) < 0) - scan = scan->right; - else - return scan; - } - return ((void *)0); -} -static unsigned char ts_impl_h(struct treeset_node *node) -{ - if (node == ((void *)0)) - return 0; - return node->height; -} -static unsigned char ts_impl_hupdate(struct treeset_node *node) -{ - if (node == ((void *)0)) - return 0; - unsigned char h_l = ts_impl_h(node->left); - unsigned char h_r = ts_impl_h(node->right); - return 1 + (h_l > h_r ? h_l : h_r); -} -static void ts_impl_rotate_right(struct treeset_node **Z) -{ - struct treeset_node *root = *Z; - struct treeset_node *new_root = root->left; - if (root->parent != ((void *)0)) - { - if (root->parent->left == root) - root->parent->left = new_root; - else - root->parent->right = new_root; - } - new_root->parent = root->parent; - root->parent = new_root; - root->left = new_root->right; - if (root->left) - root->left->parent = root; - new_root->right = root; - root->height = ts_impl_hupdate(root); - new_root->height = ts_impl_hupdate(new_root); - *Z = new_root; -} -static void ts_impl_rotate_left(struct treeset_node **Z) -{ - struct treeset_node *root = *Z; - struct treeset_node *new_root = root->right; - if (root->parent != ((void *)0)) - { - if (root->parent->right == root) - root->parent->right = new_root; - else - root->parent->left = new_root; - } - new_root->parent = root->parent; - root->parent = new_root; - root->right = new_root->left; - if (root->right) - root->right->parent = root; - new_root->left = root; - root->height = ts_impl_hupdate(root); - new_root->height = ts_impl_hupdate(new_root); - *Z = new_root; -} -static void ts_impl_rebalance(struct treeset *_set_, struct treeset_node *node) -{ - struct treeset_node *scan = node, *child = ((void *)0); - int balance; - _Bool is_root = 0; - while (scan != ((void *)0)) - { - if (scan->parent == ((void *)0)) - is_root = 1; - scan->height = ts_impl_hupdate(scan); - balance = ts_impl_h(scan->right) - ts_impl_h(scan->left); - if (balance >= 2) - { - child = scan->right; - if (ts_impl_h(child->right) < ts_impl_h(child->left)) - ts_impl_rotate_right(&(scan->right)); - ts_impl_rotate_left(&scan); - } - else if (balance <= -2) - { - child = scan->left; - if (ts_impl_h(child->left) < ts_impl_h(child->right)) - ts_impl_rotate_left(&(scan->left)); - ts_impl_rotate_right(&scan); - } - if (is_root) - { - _set_->root = scan; - is_root = 0; - } - scan = scan->parent; - } -} -struct treeset_iter ts_iter_start(struct treeset *target) -{ - struct treeset_iter iter; - iter.target = target; - iter.cursor = target->root; - iter.first = ((void *)0); - iter.last = ((void *)0); - iter.index = 0; - iter.start = 1; - iter.end = ts_empty(target); - if (!ts_empty(target)) - { - while (iter.cursor->left != ((void *)0)) - iter.cursor = iter.cursor->left; - iter.first = iter.cursor; - iter.last = target->root; - while (iter.last->right != ((void *)0)) - iter.last = iter.last->right; - } - return iter; -} -struct treeset_iter ts_iter_end(struct treeset *target) -{ - struct treeset_iter iter; - iter.target = target; - iter.cursor = target->root; - iter.first = ((void *)0); - iter.last = ((void *)0); - iter.index = 0; - iter.start = ts_empty(target); - iter.end = 1; - if (!ts_empty(target)) - { - while (iter.cursor->right != ((void *)0)) - iter.cursor = iter.cursor->right; - iter.last = iter.cursor; - iter.first = target->root; - while (iter.first->left != ((void *)0)) - iter.first = iter.first->left; - iter.index = target->count - 1; - } - return iter; -} -_Bool ts_iter_at_start(struct treeset_iter *iter) -{ - return ts_empty(iter->target) || iter->start; -} -_Bool ts_iter_at_end(struct treeset_iter *iter) -{ - return ts_empty(iter->target) || iter->end; -} -_Bool ts_iter_to_start(struct treeset_iter *iter) -{ - if (!ts_empty(iter->target)) - { - iter->index = 0; - iter->start = 1; - iter->end = ts_empty(iter->target); - iter->cursor = iter->first; - return 1; - } - return 0; -} -_Bool ts_iter_to_end(struct treeset_iter *iter) -{ - if (!ts_empty(iter->target)) - { - iter->index = iter->target->count - 1; - iter->start = ts_empty(iter->target); - iter->end = 1; - iter->cursor = iter->last; - return 1; - } - return 0; -} -_Bool ts_iter_next(struct treeset_iter *iter) -{ - if (iter->end) - return 0; - if (iter->cursor == iter->last) - { - iter->end = 1; - return 0; - } - iter->start = ts_empty(iter->target); - if (iter->cursor->right != ((void *)0)) - { - iter->cursor = iter->cursor->right; - while (iter->cursor->left != ((void *)0)) - iter->cursor = iter->cursor->left; - iter->index++; - return 1; - } - while (1) - { - if (iter->cursor->parent->left == iter->cursor) - { - iter->cursor = iter->cursor->parent; - iter->index++; - return 1; - } - iter->cursor = iter->cursor->parent; - } -} -_Bool ts_iter_prev(struct treeset_iter *iter) -{ - if (iter->start) - return 0; - if (iter->cursor == iter->first) - { - iter->start = 1; - return 0; - } - iter->end = ts_empty(iter->target); - if (iter->cursor->left != ((void *)0)) - { - iter->cursor = iter->cursor->left; - while (iter->cursor->right != ((void *)0)) - iter->cursor = iter->cursor->right; - iter->index--; - return 1; - } - while (1) - { - if (iter->cursor->parent->right == iter->cursor) - { - iter->cursor = iter->cursor->parent; - iter->index--; - return 1; - } - iter->cursor = iter->cursor->parent; - } -} -_Bool ts_iter_advance(struct treeset_iter *iter, size_t steps) -{ - if (iter->end) - return 0; - if (iter->cursor == iter->last) - { - iter->end = 1; - return 0; - } - if (steps == 0 || iter->index + steps >= iter->target->count) - return 0; - for (size_t i = 0; i < steps; i++) - ts_iter_next(iter); - return 1; -} -_Bool ts_iter_rewind(struct treeset_iter *iter, size_t steps) -{ - if (iter->start) - return 0; - if (iter->cursor == iter->first) - { - iter->start = 1; - return 0; - } - if (steps == 0 || iter->index < steps) - return 0; - for (size_t i = 0; i < steps; i++) - ts_iter_prev(iter); - return 1; -} -_Bool ts_iter_go_to(struct treeset_iter *iter, size_t index) -{ - if (index >= iter->target->count) - return 0; - if (iter->index > index) - return ts_iter_rewind(iter, iter->index - index); - else if (iter->index < index) - return ts_iter_advance(iter, index - iter->index); - return 1; -} -size_t ts_iter_value(struct treeset_iter *iter) -{ - if (ts_empty(iter->target)) - return (size_t){ 0 }; - return iter->cursor->value; -} -size_t ts_iter_index(struct treeset_iter *iter) -{ - return iter->index; -} -struct treeset *ts_union(struct treeset *_set1_, struct treeset *_set2_) -{ - struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - return ((void *)0); - struct treeset_iter iter1 = ts_iter_start(_set1_); - struct treeset_iter iter2 = ts_iter_start(_set2_); - for (; !ts_iter_at_end(&iter1); ts_iter_next(&iter1)) - { - ts_insert(_set_r_, ts_iter_value(&iter1)); - } - for (; !ts_iter_at_end(&iter2); ts_iter_next(&iter2)) - { - ts_insert(_set_r_, ts_iter_value(&iter2)); - } - (_set_r_)->callbacks = _set1_->callbacks; - return _set_r_; -} -struct treeset *ts_intersection(struct treeset *_set1_, struct treeset *_set2_) -{ - struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - return ((void *)0); - struct treeset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; - struct treeset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; - struct treeset_iter iter = ts_iter_start(_set_A_); - for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) - { - size_t value = ts_iter_value(&iter); - if (ts_impl_get_node(_set_B_, value) != ((void *)0)) - ts_insert(_set_r_, value); - } - (_set_r_)->callbacks = _set1_->callbacks; - return _set_r_; -} -struct treeset *ts_difference(struct treeset *_set1_, struct treeset *_set2_) -{ - struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - return ((void *)0); - struct treeset_iter iter = ts_iter_start(_set1_); - for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) - { - size_t value = ts_iter_value(&iter); - if (ts_impl_get_node(_set2_, value) == ((void *)0)) - ts_insert(_set_r_, value); - } - (_set_r_)->callbacks = _set1_->callbacks; - return _set_r_; -} -struct treeset *ts_symmetric_difference(struct treeset *_set1_, struct treeset *_set2_) -{ - struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0)); - if (!_set_r_) - return ((void *)0); - struct treeset_iter iter1 = ts_iter_start(_set1_); - struct treeset_iter iter2 = ts_iter_start(_set2_); - for (; !ts_iter_at_end(&iter1); ts_iter_next(&iter1)) - { - size_t value = ts_iter_value(&iter1); - if (ts_impl_get_node(_set2_, value) == ((void *)0)) - ts_insert(_set_r_, value); - } - for (; !ts_iter_at_end(&iter2); ts_iter_next(&iter2)) - { - size_t value = ts_iter_value(&iter2); - if (ts_impl_get_node(_set1_, value) == ((void *)0)) - ts_insert(_set_r_, value); - } - (_set_r_)->callbacks = _set1_->callbacks; - return _set_r_; -} -_Bool ts_is_subset(struct treeset *_set1_, struct treeset *_set2_) -{ - if (_set1_->count > _set2_->count) - return 0; - if (ts_empty(_set1_)) - return 1; - struct treeset_iter iter = ts_iter_start(_set1_); - for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) - { - size_t value = ts_iter_value(&iter); - if (ts_impl_get_node(_set2_, value) == ((void *)0)) - return 0; - } - return 1; -} -_Bool ts_is_superset(struct treeset *_set1_, struct treeset *_set2_) -{ - return ts_is_subset(_set2_, _set1_); -} -_Bool ts_is_proper_subset(struct treeset *_set1_, struct treeset *_set2_) -{ - if (_set1_->count >= _set2_->count) - return 0; - if (ts_empty(_set1_)) - { - if (!ts_empty(_set2_)) - return 1; - else - return 0; - } - struct treeset_iter iter = ts_iter_start(_set1_); - for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) - { - size_t value = ts_iter_value(&iter); - if (ts_impl_get_node(_set2_, value) == ((void *)0)) - return 0; - } - return 1; -} -_Bool ts_is_proper_superset(struct treeset *_set1_, struct treeset *_set2_) -{ - return ts_is_proper_subset(_set2_, _set1_); -} -_Bool ts_is_disjointset(struct treeset *_set1_, struct treeset *_set2_) -{ - if (ts_empty(_set1_)) - return 1; - struct treeset_iter iter = ts_iter_start(_set1_); - for (; !ts_iter_at_end(&iter); ts_iter_next(&iter)) - { - size_t value = ts_iter_value(&iter); - if (ts_impl_get_node(_set2_, value) != ((void *)0)) - return 0; - } - return 1; -} -_Bool ts_to_string(struct treeset *_set_, FILE *fptr) -{ - struct treeset *s_ = _set_; - return 0 <= fprintf(fptr, - "struct %s<%s> " - "at %p { " - "root:%p, " - "count:%" - "I64u" - ", " - "flag:%d, " - "f_val:%p, " - "alloc:%p, " - "callbacks:%p }", - "treeset", "size_t", s_, s_->root, s_->count, s_->flag, s_->f_val, s_->alloc, (s_)->callbacks); -} -_Bool ts_print(struct treeset *_set_, FILE *fptr, const char *start, const char *separator, const char *end) -{ - fprintf(fptr, "%s", start); - struct treeset_node *root = _set_->root; - _Bool left_done = 0; - size_t i = 0; - while (root) - { - if (!left_done) - { - while (root->left) - root = root->left; - } - if (!_set_->f_val->str(fptr, root->value)) - return 0; - if (++i < _set_->count) - fprintf(fptr, "%s", separator); - left_done = 1; - if (root->right) - { - left_done = 0; - root = root->right; - } - else if (root->parent) - { - while (root->parent && root == root->parent->right) - root = root->parent; - if (!root->parent) - break; - root = root->parent; - } - else - break; - } - fprintf(fptr, "%s", end); - return 1; -} diff --git a/tests/to_string.c b/tests/to_string.c deleted file mode 100644 index df8b926..0000000 --- a/tests/to_string.c +++ /dev/null @@ -1,208 +0,0 @@ -// A visual check for to_string methods - -#include "macro_collections.h" - -// clang-format off -C_MACRO_COLLECTIONS_ALL(CMC, BITSET, ( bs, bitset, , , )) -C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d, deque, , , int)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm, hashbidimap, , int, int)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, ( hm, hashmap, , int, int)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm, hashmultimap, , int, int)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms, hashmultiset, , , int)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, ( hs, hashset, , , int)) -C_MACRO_COLLECTIONS_ALL(CMC, HEAP, ( h, heap, , , int)) -C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, ( ih, intervalheap, , , int)) -C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, ( ll, linkedlist, , , int)) -C_MACRO_COLLECTIONS_ALL(CMC, LIST, ( l, list, , , int)) -C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, ( q, queue, , , int)) -C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, ( sl, sortedlist, , , int)) -C_MACRO_COLLECTIONS_ALL(CMC, STACK, ( s, stack, , , int)) -C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, ( tm, treemap, , int, int)) -C_MACRO_COLLECTIONS_ALL(CMC, TREESET, ( ts, treeset, , , int)) - -struct -{ - CMC_DEF_FTAB_CMP(int); - CMC_DEF_FTAB_CPY(int); - CMC_DEF_FTAB_STR(int); - CMC_DEF_FTAB_FREE(int); - CMC_DEF_FTAB_HASH(int); - CMC_DEF_FTAB_PRI(int); -} int_ftab = {cmc_i32_cmp, NULL, cmc_i32_str, NULL, cmc_i32_hash, cmc_i32_cmp}; - -int main(void) -{ - struct deque *d = d_new(100, (struct deque_fval *)&int_ftab); - struct hashbidimap *hbm = hbm_new(100, 0.8, - (struct hashbidimap_fkey *)&int_ftab, - (struct hashbidimap_fval *)&int_ftab); - struct hashmap *hm = hm_new(100, 0.6, (struct hashmap_fkey *)&int_ftab, - (struct hashmap_fval *)&int_ftab); - struct hashmultimap *hmm = hmm_new(100, 0.8, - (struct hashmultimap_fkey *)&int_ftab, - (struct hashmultimap_fval *)&int_ftab); - struct hashmultiset *hms = hms_new(100, 0.6, - (struct hashmultiset_fval *)&int_ftab); - struct hashset *hs = hs_new(100, 0.6, - (struct hashset_fval *)&int_ftab); - struct heap *h = h_new(100, CMC_MAX_HEAP, (struct heap_fval *)&int_ftab); - struct intervalheap *ih = ih_new(100, (struct intervalheap_fval *)&int_ftab); - struct linkedlist *ll = ll_new((struct linkedlist_fval *)&int_ftab); - struct list *l = l_new(100, (struct list_fval *)&int_ftab); - struct queue *q = q_new(100, (struct queue_fval *)&int_ftab); - struct sortedlist *sl = sl_new(100, (struct sortedlist_fval *)&int_ftab); - struct stack *s = s_new(100, (struct stack_fval *)&int_ftab); - struct treemap *tm = tm_new((struct treemap_fkey *)&int_ftab, - (struct treemap_fval *)&int_ftab); - struct treeset *ts = ts_new((struct treeset_fval *)&int_ftab); - - d_to_string(d, stdout); - d_print(d, stdout, "\n[ ", ", ", " ]\n"); - hbm_to_string(hbm, stdout); - hbm_print(hbm, stdout, "\n[ {", "}, {", "} ]\n", " : "); - hm_to_string(hm, stdout); - hm_print(hm, stdout, "\n[ {", "}, {", "} ]\n", " : "); - hmm_to_string(hmm, stdout); - hmm_print(hmm, stdout, "\n[ {", "}, {", "} ]\n", " : "); - hms_to_string(hms, stdout); - hms_print(hms, stdout, "\n[ {", "}, {", "} ]\n", " : "); - hs_to_string(hs, stdout); - hs_print(hs, stdout, "\n[ ", ", ", " ]\n"); - h_to_string(h, stdout); - h_print(h, stdout, "\n[ ", ", ", " ]\n"); - ih_to_string(ih, stdout); - ih_print(ih, stdout, "\n[ ", ", ", " ]\n"); - ll_to_string(ll, stdout); - ll_print(ll, stdout, "\n[ ", ", ", " ]\n"); - l_to_string(l, stdout); - l_print(l, stdout, "\n[ ", ", ", " ]\n"); - q_to_string(q, stdout); - q_print(q, stdout, "\n[ ", ", ", " ]\n"); - sl_to_string(sl, stdout); - sl_print(sl, stdout, "\n[ ", ", ", " ]\n"); - s_to_string(s, stdout); - s_print(s, stdout, "\n[ ", ", ", " ]\n"); - tm_to_string(tm, stdout); - tm_print(tm, stdout, "\n[ {", "}, {", "} ]\n", " : "); - ts_to_string(ts, stdout); - ts_print(ts, stdout, "\n[ ", ", ", " ]\n"); - - fprintf(stdout, "\n"); - - d_push_back(d, 0); - hbm_insert(hbm, 0, 0); - hm_insert(hm, 0, 0); - hmm_insert(hmm, 0, 0); - hms_insert(hms, 0); - hs_insert(hs, 0); - h_insert(h, 0); - ih_insert(ih, 0); - ll_push_back(ll, 0); - l_push_back(l, 0); - q_enqueue(q, 0); - sl_insert(sl, 0); - s_push(s, 0); - tm_insert(tm, 0, 0); - ts_insert(ts, 0); - - d_to_string(d, stdout); - d_print(d, stdout, "\n[ ", ", ", " ]\n"); - hbm_to_string(hbm, stdout); - hbm_print(hbm, stdout, "\n[ {", "}, {", "} ]\n", " : "); - hm_to_string(hm, stdout); - hm_print(hm, stdout, "\n[ {", "}, {", "} ]\n", " : "); - hmm_to_string(hmm, stdout); - hmm_print(hmm, stdout, "\n[ {", "}, {", "} ]\n", " : "); - hms_to_string(hms, stdout); - hms_print(hms, stdout, "\n[ {", "}, {", "} ]\n", " : "); - hs_to_string(hs, stdout); - hs_print(hs, stdout, "\n[ ", ", ", " ]\n"); - h_to_string(h, stdout); - h_print(h, stdout, "\n[ ", ", ", " ]\n"); - ih_to_string(ih, stdout); - ih_print(ih, stdout, "\n[ ", ", ", " ]\n"); - ll_to_string(ll, stdout); - ll_print(ll, stdout, "\n[ ", ", ", " ]\n"); - l_to_string(l, stdout); - l_print(l, stdout, "\n[ ", ", ", " ]\n"); - q_to_string(q, stdout); - q_print(q, stdout, "\n[ ", ", ", " ]\n"); - sl_to_string(sl, stdout); - sl_print(sl, stdout, "\n[ ", ", ", " ]\n"); - s_to_string(s, stdout); - s_print(s, stdout, "\n[ ", ", ", " ]\n"); - tm_to_string(tm, stdout); - tm_print(tm, stdout, "\n[ {", "}, {", "} ]\n", " : "); - ts_to_string(ts, stdout); - ts_print(ts, stdout, "\n[ ", ", ", " ]\n"); - - for (int i = 1; i < 20; i++) - { - d_push_back(d, i); - hbm_insert(hbm, i, i); - hm_insert(hm, i, i); - hmm_insert(hmm, i, i); - hms_insert(hms, i); - hs_insert(hs, i); - h_insert(h, i); - ih_insert(ih, i); - ll_push_back(ll, i); - l_push_back(l, i); - q_enqueue(q, i); - sl_insert(sl, i); - s_push(s, i); - tm_insert(tm, i, i); - ts_insert(ts, i); - } - - fprintf(stdout, "\n"); - - d_to_string(d, stdout); - d_print(d, stdout, "\n[ ", ", ", " ]\n"); - hbm_to_string(hbm, stdout); - hbm_print(hbm, stdout, "\n[ {", "}, {", "} ]\n", " : "); - hm_to_string(hm, stdout); - hm_print(hm, stdout, "\n[ {", "}, {", "} ]\n", " : "); - hmm_to_string(hmm, stdout); - hmm_print(hmm, stdout, "\n[ {", "}, {", "} ]\n", " : "); - hms_to_string(hms, stdout); - hms_print(hms, stdout, "\n[ {", "}, {", "} ]\n", " : "); - hs_to_string(hs, stdout); - hs_print(hs, stdout, "\n[ ", ", ", " ]\n"); - h_to_string(h, stdout); - h_print(h, stdout, "\n[ ", ", ", " ]\n"); - ih_to_string(ih, stdout); - ih_print(ih, stdout, "\n[ ", ", ", " ]\n"); - ll_to_string(ll, stdout); - ll_print(ll, stdout, "\n[ ", ", ", " ]\n"); - l_to_string(l, stdout); - l_print(l, stdout, "\n[ ", ", ", " ]\n"); - q_to_string(q, stdout); - q_print(q, stdout, "\n[ ", ", ", " ]\n"); - sl_to_string(sl, stdout); - sl_print(sl, stdout, "\n[ ", ", ", " ]\n"); - s_to_string(s, stdout); - s_print(s, stdout, "\n[ ", ", ", " ]\n"); - tm_to_string(tm, stdout); - tm_print(tm, stdout, "\n[ {", "}, {", "} ]\n", " : "); - ts_to_string(ts, stdout); - ts_print(ts, stdout, "\n[ ", ", ", " ]\n"); - - d_free(d); - hbm_free(hbm); - hm_free(hm); - hmm_free(hmm); - hms_free(hms); - hs_free(hs); - h_free(h); - ih_free(ih); - ll_free(ll); - l_free(l); - q_free(q); - sl_free(sl); - s_free(s); - tm_free(tm); - ts_free(ts); -} - -// clang-format on diff --git a/tests/types.c b/tests/types.c deleted file mode 100644 index ec6678f..0000000 --- a/tests/types.c +++ /dev/null @@ -1,197 +0,0 @@ -// Tests all containers if they accept all C data types -// Compile with -Wall -Wextra -#include "../src/macro_collections.h" -#include - -typedef struct struct_s -{ - int a, b; - char *c, *d; - double e[10]; -} struct_t; - -typedef enum enum_e -{ - HELLO, - WORLD, - NONE = 0 -} enum_t; - -typedef union union_u -{ - enum enum_e a; - struct struct_s b; - double c; - char *d; -} union_t; - -typedef int(func_t)(int, double, char *); - -C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, (d0, deque0, , , struct_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm0, hashbidimap0, , struct_t *, struct_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, (hm0, hashmap0, , struct_t *, struct_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm0, hashmultimap0, , struct_t *, struct_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms0, hashmultiset0, , , struct_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, (hs0, hashset0, , , struct_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HEAP, (h0, heap0, , , struct_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, (ih0, intervalheap0, , , struct_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, (ll0, linkedlist0, , , struct_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, LIST, (l0, list0, , , struct_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, (q0, queue0, , , struct_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, (sl0, sortedlist0, , , struct_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, STACK, (s0, stack0, , , struct_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, (tm0, treemap0, , struct_t *, struct_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, TREESET, (ts0, treeset0, , , struct_t *)) - -C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, (d1, deque1, , , struct_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm1, hashbidimap1, , struct_t, struct_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, (hm1, hashmap1, , struct_t, struct_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm1, hashmultimap1, , struct_t, struct_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms1, hashmultiset1, , , struct_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, (hs1, hashset1, , , struct_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HEAP, (h1, heap1, , , struct_t)) -C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, (ih1, intervalheap1, , , struct_t)) -C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, (ll1, linkedlist1, , , struct_t)) -C_MACRO_COLLECTIONS_ALL(CMC, LIST, (l1, list1, , , struct_t)) -C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, (q1, queue1, , , struct_t)) -C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, (sl1, sortedlist1, , , struct_t)) -C_MACRO_COLLECTIONS_ALL(CMC, STACK, (s1, stack1, , , struct_t)) -C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, (tm1, treemap1, , struct_t, struct_t)) -C_MACRO_COLLECTIONS_ALL(CMC, TREESET, (ts1, treeset1, , , struct_t)) - -C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, (d2, deque2, , , int)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm2, hashbidimap2, , int, int)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, (hm2, hashmap2, , int, int)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm2, hashmultimap2, , int, int)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms2, hashmultiset2, , , int)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, (hs2, hashset2, , , int)) -C_MACRO_COLLECTIONS_ALL(CMC, HEAP, (h2, heap2, , , int)) -C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, (ih2, intervalheap2, , , int)) -C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, (ll2, linkedlist2, , , int)) -C_MACRO_COLLECTIONS_ALL(CMC, LIST, (l2, list2, , , int)) -C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, (q2, queue2, , , int)) -C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, (sl2, sortedlist2, , , int)) -C_MACRO_COLLECTIONS_ALL(CMC, STACK, (s2, stack2, , , int)) -C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, (tm2, treemap2, , int, int)) -C_MACRO_COLLECTIONS_ALL(CMC, TREESET, (ts2, treeset2, , , int)) - -C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, (d3, deque3, , , int *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm3, hashbidimap3, , int *, int *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, (hm3, hashmap3, , int *, int *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm3, hashmultimap3, , int *, int *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms3, hashmultiset3, , , int *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, (hs3, hashset3, , , int *)) -C_MACRO_COLLECTIONS_ALL(CMC, HEAP, (h3, heap3, , , int *)) -C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, (ih3, intervalheap3, , , int *)) -C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, (ll3, linkedlist3, , , int *)) -C_MACRO_COLLECTIONS_ALL(CMC, LIST, (l3, list3, , , int *)) -C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, (q3, queue3, , , int *)) -C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, (sl3, sortedlist3, , , int *)) -C_MACRO_COLLECTIONS_ALL(CMC, STACK, (s3, stack3, , , int *)) -C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, (tm3, treemap3, , int *, int *)) -C_MACRO_COLLECTIONS_ALL(CMC, TREESET, (ts3, treeset3, , , int *)) - -C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, (d4, deque4, , , enum_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm4, hashbidimap4, , enum_t, enum_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, (hm4, hashmap4, , enum_t, enum_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm4, hashmultimap4, , enum_t, enum_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms4, hashmultiset4, , , enum_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, (hs4, hashset4, , , enum_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HEAP, (h4, heap4, , , enum_t)) -C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, (ih4, intervalheap4, , , enum_t)) -C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, (ll4, linkedlist4, , , enum_t)) -C_MACRO_COLLECTIONS_ALL(CMC, LIST, (l4, list4, , , enum_t)) -C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, (q4, queue4, , , enum_t)) -C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, (sl4, sortedlist4, , , enum_t)) -C_MACRO_COLLECTIONS_ALL(CMC, STACK, (s4, stack4, , , enum_t)) -C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, (tm4, treemap4, , enum_t, enum_t)) -C_MACRO_COLLECTIONS_ALL(CMC, TREESET, (ts4, treeset4, , , enum_t)) - -C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, (d5, deque5, , , enum_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm5, hashbidimap5, , enum_t *, enum_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, (hm5, hashmap5, , enum_t *, enum_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm5, hashmultimap5, , enum_t *, enum_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms5, hashmultiset5, , , enum_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, (hs5, hashset5, , , enum_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HEAP, (h5, heap5, , , enum_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, (ih5, intervalheap5, , , enum_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, (ll5, linkedlist5, , , enum_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, LIST, (l5, list5, , , enum_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, (q5, queue5, , , enum_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, (sl5, sortedlist5, , , enum_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, STACK, (s5, stack5, , , enum_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, (tm5, treemap5, , enum_t *, enum_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, TREESET, (ts5, treeset5, , , enum_t *)) - -C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, (d6, deque6, , , union_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm6, hashbidimap6, , union_t, union_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, (hm6, hashmap6, , union_t, union_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm6, hashmultimap6, , union_t, union_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms6, hashmultiset6, , , union_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, (hs6, hashset6, , , union_t)) -C_MACRO_COLLECTIONS_ALL(CMC, HEAP, (h6, heap6, , , union_t)) -C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, (ih6, intervalheap6, , , union_t)) -C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, (ll6, linkedlist6, , , union_t)) -C_MACRO_COLLECTIONS_ALL(CMC, LIST, (l6, list6, , , union_t)) -C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, (q6, queue6, , , union_t)) -C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, (sl6, sortedlist6, , , union_t)) -C_MACRO_COLLECTIONS_ALL(CMC, STACK, (s6, stack6, , , union_t)) -C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, (tm6, treemap6, , union_t, union_t)) -C_MACRO_COLLECTIONS_ALL(CMC, TREESET, (ts6, treeset6, , , union_t)) - -C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, (d7, deque7, , , union_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm7, hashbidimap7, , union_t *, union_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, (hm7, hashmap7, , union_t *, union_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm7, hashmultimap7, , union_t *, union_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms7, hashmultiset7, , , union_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, (hs7, hashset7, , , union_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HEAP, (h7, heap7, , , union_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, (ih7, intervalheap7, , , union_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, (ll7, linkedlist7, , , union_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, LIST, (l7, list7, , , union_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, (q7, queue7, , , union_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, (sl7, sortedlist7, , , union_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, STACK, (s7, stack7, , , union_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, (tm7, treemap7, , union_t *, union_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, TREESET, (ts7, treeset7, , , union_t *)) - -// C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d8, deque8, , , func_t)) -// C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm8, hashbidimap8, , func_t, func_t)) -// C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, ( hm8, hashmap8, , func_t, func_t)) -// C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm8, hashmultimap8, , func_t, func_t)) -// C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms8, hashmultiset8, , , func_t)) -// C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, ( hs8, hashset8, , , func_t)) -// C_MACRO_COLLECTIONS_ALL(CMC, HEAP, ( h8, heap8, , , func_t)) -// C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, ( ih8, intervalheap8, , , func_t)) -// C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, ( ll8, linkedlist8, , , func_t)) -// C_MACRO_COLLECTIONS_ALL(CMC, LIST, ( l8, list8, , , func_t)) -// C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, ( q8, queue8, , , func_t)) -// C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, ( sl8, sortedlist8, , , func_t)) -// C_MACRO_COLLECTIONS_ALL(CMC, STACK, ( s8, stack8, , , func_t)) -// C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, ( tm8, treemap8, , func_t, func_t)) -// C_MACRO_COLLECTIONS_ALL(CMC, TREESET, ( ts8, treeset8, , , func_t)) - -C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, (d9, deque9, , , func_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm9, hashbidimap9, , func_t *, func_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, (hm9, hashmap9, , func_t *, func_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm9, hashmultimap9, , func_t *, func_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms9, hashmultiset9, , , func_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, (hs9, hashset9, , , func_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, HEAP, (h9, heap9, , , func_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, (ih9, intervalheap9, , , func_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, (ll9, linkedlist9, , , func_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, LIST, (l9, list9, , , func_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, (q9, queue9, , , func_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, (sl9, sortedlist9, , , func_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, STACK, (s9, stack9, , , func_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, (tm9, treemap9, , func_t *, func_t *)) -C_MACRO_COLLECTIONS_ALL(CMC, TREESET, (ts9, treeset9, , , func_t *)) - -int main(void) -{ - printf("+--------------------------------------------------+\n"); - printf("| All Data Types Are Working |\n"); - printf("+--------------------------------------------------+\n"); - - return 0; -} diff --git a/tests/unt/unt_cmc_bitset.h b/tests/unt/unt_cmc_bitset.h deleted file mode 100644 index f54fed2..0000000 --- a/tests/unt/unt_cmc_bitset.h +++ /dev/null @@ -1,464 +0,0 @@ -#ifndef CMC_TESTS_UNT_CMC_ITSET_H -#define CMC_TESTS_UNT_CMC_ITSET_H - -#include "utl.h" - -#include "tst_cmc_bitset.h" - -struct cmc_alloc_node *bs_alloc_node = - &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free }; - -CMC_CREATE_UNIT(CMCBitSet, true, { - const size_t word_bits = sizeof(cmc_bitset_word) * CHAR_BIT; - - printf("%s", cmc_test_color(5)); - printf(" BitSet<" CMC_TO_STRING(CMC_BITSET_WORD_TYPE) ">\n"); - printf("%s", cmc_test_color(0)); - - CMC_CREATE_TEST(PFX##_new(), { - struct bitset *bs = bs_new(64); - - cmc_assert_not_equals(ptr, NULL, bs); - cmc_assert_not_equals(ptr, NULL, bs->buffer); - cmc_assert_equals(size_t, cmc_bidx_to_widx(63) + 1, bs->capacity); - cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, bs->alloc->malloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, bs->alloc->calloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, bs->alloc->realloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.free, bs->alloc->free); - cmc_assert_equals(ptr, NULL, bs->callbacks); - - bs_free(bs); - - bs = bs_new(129); - - cmc_assert_equals(size_t, cmc_bidx_to_widx(128) + 1, bs->capacity); - - bs_free(bs); - - bs = bs_new(0); - - cmc_assert_equals(ptr, NULL, bs); - }); - - CMC_CREATE_TEST(PFX##_new_custom(), { - struct bitset *bs = bs_new_custom(64, bs_alloc_node, callbacks); - - cmc_assert_not_equals(ptr, NULL, bs); - cmc_assert_not_equals(ptr, NULL, bs->buffer); - cmc_assert_equals(size_t, cmc_bidx_to_widx(63) + 1, bs->capacity); - cmc_assert_equals(ptr, bs_alloc_node, bs->alloc); - cmc_assert_equals(ptr, callbacks, bs->callbacks); - - bs_free(bs); - - bs = bs_new_custom(129, NULL, NULL); - - cmc_assert_equals(size_t, cmc_bidx_to_widx(128) + 1, bs->capacity); - bs_free(bs); - - bs = bs_new_custom(0, bs_alloc_node, callbacks); - - cmc_assert_equals(ptr, NULL, bs); - }); - - CMC_CREATE_TEST(PFX##_init(), { - struct bitset bs = bs_init(64); - - cmc_assert_not_equals(ptr, NULL, bs.buffer); - cmc_assert_equals(size_t, cmc_bidx_to_widx(63) + 1, bs.capacity); - cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, bs.alloc->malloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, bs.alloc->calloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, bs.alloc->realloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.free, bs.alloc->free); - cmc_assert_equals(ptr, NULL, bs.callbacks); - - bs_release(bs); - - bs = bs_init(129); - - cmc_assert_equals(size_t, cmc_bidx_to_widx(128) + 1, bs.capacity); - - bs_release(bs); - - bs = bs_init(0); - - cmc_assert_equals(ptr, NULL, bs.buffer); - }); - - CMC_CREATE_TEST(PFX##_init_custom(), { - struct bitset bs = bs_init_custom(64, bs_alloc_node, callbacks); - - cmc_assert_not_equals(ptr, NULL, bs.buffer); - cmc_assert_equals(size_t, cmc_bidx_to_widx(63) + 1, bs.capacity); - cmc_assert_equals(ptr, bs_alloc_node, bs.alloc); - cmc_assert_equals(ptr, callbacks, bs.callbacks); - - bs_release(bs); - - bs = bs_init_custom(129, NULL, NULL); - - cmc_assert_equals(size_t, cmc_bidx_to_widx(128) + 1, bs.capacity); - - bs_release(bs); - - bs = bs_init_custom(0, bs_alloc_node, callbacks); - - cmc_assert_equals(ptr, NULL, bs.buffer); - }); - - CMC_CREATE_TEST(PFX##_customize(), { - struct bitset *bs = bs_new(word_bits); - - cmc_assert_not_equals(ptr, NULL, bs); - - bs->flag = CMC_FLAG_ERROR; - bs_customize(bs, bs_alloc_node, callbacks); - - cmc_assert_equals(ptr, bs_alloc_node, bs->alloc); - cmc_assert_equals(ptr, callbacks, bs->callbacks); - cmc_assert_equals(int32_t, CMC_FLAG_OK, bs->flag); - - bs->flag = CMC_FLAG_ERROR; - bs_customize(bs, NULL, NULL); - - cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, bs->alloc->malloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, bs->alloc->calloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, bs->alloc->realloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.free, bs->alloc->free); - cmc_assert_equals(ptr, NULL, bs->callbacks); - cmc_assert_equals(int32_t, CMC_FLAG_OK, bs->flag); - - bs_free(bs); - }); - - CMC_CREATE_TEST(PFX##_set(), { - struct bitset *bs = bs_new(word_bits); - - cmc_assert_not_equals(ptr, NULL, bs); - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]); - - bs->flag = CMC_FLAG_ERROR; - cmc_assert(bs_set(bs, 0)); - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 1, bs->buffer[0]); - cmc_assert_equals(int32_t, CMC_FLAG_OK, bs->flag); - - bs->buffer[0] = 0; - - cmc_assert(bs_set(bs, word_bits - 1)); - cmc_assert_equals(CMC_BITSET_WORD_TYPE, ((cmc_bitset_word)1 << (word_bits - 1)), bs->buffer[0]); - - cmc_assert(bs_set(bs, word_bits * 8 - 1)); - cmc_assert_equals(CMC_BITSET_WORD_TYPE, ((cmc_bitset_word)1 << (word_bits - 1)), - bs->buffer[cmc_bidx_to_widx(word_bits * 8 - 1)]); - - cmc_assert(bs_set(bs, word_bits * 18 - 2)); - cmc_assert_equals(CMC_BITSET_WORD_TYPE, ((cmc_bitset_word)1 << (word_bits - 2)), - bs->buffer[cmc_bidx_to_widx(word_bits * 18 - 2)]); - - bs_free(bs); - }); - - CMC_CREATE_TEST(PFX##_set_range(), { - struct bitset *bs = bs_new(word_bits); - - cmc_assert_not_equals(ptr, NULL, bs); - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]); - - bs->flag = CMC_FLAG_ERROR; - cmc_assert(bs_set_range(bs, 0, 0)); - cmc_assert_equals(uint8_t, 1, bs->buffer[0]); - cmc_assert_equals(int32_t, CMC_FLAG_OK, bs->flag); - - cmc_assert(!bs_set_range(bs, 1, 0)); - cmc_assert_equals(int32_t, CMC_FLAG_INVALID, bs->flag); - - bs->buffer[0] = 0; - - cmc_assert(bs_set_range(bs, 4, 7)); /* 1111 0000 */ - cmc_assert_equals(uint8_t, 240, bs->buffer[0]); - - cmc_assert(bs_set_range(bs, 2, 2)); /* 1111 0100 */ - cmc_assert_equals(uint8_t, 244, bs->buffer[0]); - - cmc_assert(bs_set_range(bs, word_bits * 6 - 2, word_bits * 6 - 2)); - cmc_assert_equals(CMC_BITSET_WORD_TYPE, ((cmc_bitset_word)1 << (word_bits - 2)), - bs->buffer[cmc_bidx_to_widx(word_bits * 6 - 2)]); - - // Make sure we have at least word_bits * 40 slots - bs_set(bs, word_bits * 40); - - cmc_assert(bs_set_range(bs, word_bits * 20, word_bits * 21 - 1)); - cmc_assert_equals(CMC_BITSET_WORD_TYPE, (~(cmc_bitset_word)0), bs->buffer[cmc_bidx_to_widx(word_bits * 20)]); - - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[cmc_bidx_to_widx(word_bits * 20 - 1)]); - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[cmc_bidx_to_widx(word_bits * 21 + 1)]); - - cmc_assert(bs_set_range(bs, 0, word_bits * 100 - 1)); - cmc_assert_equals(size_t, 100, bs->capacity); - - for (size_t i = 0; i < bs->capacity; i++) - cmc_assert_equals(CMC_BITSET_WORD_TYPE, ~((cmc_bitset_word)0), bs->buffer[i]); - - bs_free(bs); - }); - - CMC_CREATE_TEST(PFX##_clear(), { - struct bitset *bs = bs_new(word_bits * 10 - 1); - - cmc_assert_not_equals(ptr, NULL, bs); - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]); - - bs->buffer[0] = 1; // 0001 - cmc_assert(bs_clear(bs, 0)); - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]); - - bs->buffer[0] = 10; // 1010 - cmc_assert(bs_clear(bs, 1)); - cmc_assert(bs_clear(bs, 3)); - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]); - - cmc_assert(bs_clear(bs, word_bits * 100 - 1)); - cmc_assert_equals(size_t, 100, bs->capacity); - - bs_free(bs); - }); - - CMC_CREATE_TEST(PFX##_clear_range(), { - struct bitset *bs = bs_new(word_bits * 10 - 1); - - cmc_assert_not_equals(ptr, NULL, bs); - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]); - - cmc_assert(!bs_clear_range(bs, 1, 0)); - cmc_assert_equals(int32_t, CMC_FLAG_INVALID, bs->flag); - - cmc_assert(bs_clear_range(bs, 0, word_bits * 100 - 1)); - cmc_assert_equals(size_t, 100, bs->capacity); - - cmc_assert(bs_set_range(bs, word_bits * 20, word_bits * 21 - 1)); - cmc_assert(bs_clear_range(bs, word_bits * 20, word_bits * 21 - 1)); - - cmc_assert_equals(uint32_t, 0, bs->buffer[cmc_bidx_to_widx(word_bits * 20)]); - - for (size_t i = 0; i < bs->capacity; i++) - bs->buffer[i] = ~((cmc_bitset_word)0); - - cmc_assert(bs_set_range(bs, 0, word_bits * 100 - 1)); - cmc_assert(bs_clear_range(bs, 0, word_bits * 100 - 1)); - - cmc_assert_equals(size_t, 100, bs->capacity); - - for (size_t i = 0; i < bs->capacity; i++) - cmc_assert_equals(size_t, 0, bs->buffer[0]); - - cmc_assert(bs_clear_range(bs, 0, word_bits * 200 - 1)); - cmc_assert_equals(size_t, 200, bs->capacity); - - bs_free(bs); - }); - - CMC_CREATE_TEST(PFX##_flip(), { - struct bitset *bs = bs_new(word_bits * 10 - 1); - - cmc_assert_not_equals(ptr, NULL, bs); - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]); - - cmc_assert(bs_flip(bs, 0)); - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 1, bs->buffer[0]); - - cmc_assert(bs_flip(bs, 0)); - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]); - - cmc_assert(bs_set_range(bs, 0, 2)); // 0111 - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 7, bs->buffer[0]); - cmc_assert(bs_flip(bs, 1)); // 0101 - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 5, bs->buffer[0]); - - cmc_assert(bs_flip(bs, word_bits * 100 - 1)); - cmc_assert_equals(size_t, 100, bs->capacity); - - bs_free(bs); - }); - - CMC_CREATE_TEST(PFX##_flip_range(), { - struct bitset *bs = bs_new(word_bits * 10 - 1); - - cmc_assert_not_equals(ptr, NULL, bs); - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]); - - cmc_assert(bs_flip_range(bs, 0, 0)); - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 1, bs->buffer[0]); - - cmc_assert(bs_flip_range(bs, 0, 0)); - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]); - - cmc_assert(bs_flip_range(bs, 1, 4)); // 0001 1110 - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 30, bs->buffer[0]); - - cmc_assert(bs_flip_range(bs, 2, 3)); // 0001 0010 - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 18, bs->buffer[0]); - - cmc_assert(bs_flip_range(bs, 0, 2)); // 0001 0101 - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 21, bs->buffer[0]); - - bs->buffer[0] = 0; - - cmc_assert(bs_flip_range(bs, 0, word_bits * 100 - 1)); - cmc_assert_equals(size_t, 100, bs->capacity); - - for (size_t i = 0; i < bs->capacity; i++) - cmc_assert_equals(CMC_BITSET_WORD_TYPE, ~((cmc_bitset_word)0), bs->buffer[i]); - - bs_free(bs); - }); - - CMC_CREATE_TEST(PFX##_put(), { - struct bitset *bs = bs_new(word_bits * 10 - 1); - - cmc_assert_not_equals(ptr, NULL, bs); - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]); - - cmc_assert(bs_put(bs, 1, true)); // 0010 - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 2, bs->buffer[0]); - cmc_assert(bs_put(bs, 0, false)); // 0010 - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 2, bs->buffer[0]); - cmc_assert(bs_put(bs, 1, false)); // 0000 - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]); - cmc_assert(bs_put(bs, 3, true)); // 1000 - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 8, bs->buffer[0]); - cmc_assert(bs_put(bs, 0, true)); // 1001 - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 9, bs->buffer[0]); - cmc_assert(bs_put(bs, 3, false)); // 0001 - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 1, bs->buffer[0]); - - cmc_assert(bs_put(bs, word_bits * 100 - 1, true)); - cmc_assert_equals(size_t, 100, bs->capacity); - - bs_free(bs); - }); - - CMC_CREATE_TEST(PFX##_put_range(), { - struct bitset *bs = bs_new(word_bits * 10 - 1); - - cmc_assert_not_equals(ptr, NULL, bs); - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]); - - cmc_assert(bs_put_range(bs, 1, 2, true)); // 0110 - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 6, bs->buffer[0]); - cmc_assert(bs_put_range(bs, 0, 1, false)); // 0100 - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 4, bs->buffer[0]); - cmc_assert(bs_put_range(bs, 1, 3, true)); // 1110 - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 14, bs->buffer[0]); - cmc_assert(bs_put_range(bs, 2, 3, false)); // 0010 - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 2, bs->buffer[0]); - - cmc_assert(bs_put_range(bs, 0, word_bits * 100 - 1, true)); - cmc_assert_equals(size_t, 100, bs->capacity); - - for (size_t i = 0; i < bs->capacity; i++) - cmc_assert_equals(CMC_BITSET_WORD_TYPE, ~((cmc_bitset_word)0), bs->buffer[i]); - - cmc_assert(bs_put_range(bs, 0, word_bits * 100 - 1, false)); - for (size_t i = 0; i < bs->capacity; i++) - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[i]); - - bs_free(bs); - }); - - CMC_CREATE_TEST(PFX##_set_all(), { - struct bitset *bs = bs_new(word_bits * 10 - 1); - - cmc_assert_not_equals(ptr, NULL, bs); - - cmc_assert(bs_set_all(bs)); - - for (size_t i = 0; i < bs->capacity; i++) - cmc_assert_equals(CMC_BITSET_WORD_TYPE, ~((cmc_bitset_word)0), bs->buffer[i]); - - bs_free(bs); - }); - - CMC_CREATE_TEST(PFX##_clear_all(), { - struct bitset *bs = bs_new(word_bits * 10 - 1); - - cmc_assert_not_equals(ptr, NULL, bs); - - cmc_assert(bs_set_all(bs)); - cmc_assert(bs_clear_all(bs)); - - for (size_t i = 0; i < bs->capacity; i++) - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[i]); - - bs_free(bs); - }); - - CMC_CREATE_TEST(PFX##_flip_all(), { - struct bitset *bs = bs_new(word_bits * 10 - 1); - - cmc_assert_not_equals(ptr, NULL, bs); - - cmc_assert(bs_flip_all(bs)); - for (size_t i = 0; i < bs->capacity; i++) - cmc_assert_equals(CMC_BITSET_WORD_TYPE, ~((cmc_bitset_word)0), bs->buffer[i]); - - cmc_assert(bs_flip_all(bs)); - for (size_t i = 0; i < bs->capacity; i++) - cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[i]); - - bs_free(bs); - }); - - CMC_CREATE_TEST(PFX##_get(), { - struct bitset *bs = bs_new(64); - - cmc_assert_not_equals(ptr, NULL, bs); - - cmc_assert(bs_set(bs, 1)); - - cmc_assert(bs_get(bs, 1)); - - bs_free(bs); - }); - - CMC_CREATE_TEST(PFX##_resize(), { - struct bitset *bs = bs_new(64); - - // WIP - - bs_free(bs); - }); -}); - -CMC_CREATE_UNIT(CMCBitSetIter, true, { - // const size_t word_bytes = sizeof(cmc_bitset_word); - // const size_t word_bits = sizeof(cmc_bitset_word) * CHAR_BIT; - - printf("%s", cmc_test_color(5)); - printf(" BitSet<" CMC_TO_STRING(CMC_BITSET_WORD_TYPE) ">\n"); - printf("%s", cmc_test_color(0)); - - CMC_CREATE_TEST(PFX##_iter_start(), { - struct bitset *bs = bs_new(64); - - // WIP - - bs_free(bs); - }); -}); - -#ifdef CMC_TEST_MAIN -int main(void) -{ - int result = CMCBitSet() + CMCBitSetIter(); - - printf(" +---------------------------------------------------------------+"); - printf("\n"); - printf(" | CMCBitSet Suit : %-47s |\n", result == 0 ? "PASSED" : "FAILED"); - printf(" +---------------------------------------------------------------+"); - printf("\n\n\n"); - - return result; -} -#endif - -#endif /* CMC_TESTS_UNT_CMC_ITSET_H */ diff --git a/tests/unt/unt_cmc_deque.h b/tests/unt/unt_cmc_deque.h deleted file mode 100644 index d391f41..0000000 --- a/tests/unt/unt_cmc_deque.h +++ /dev/null @@ -1,1735 +0,0 @@ -#ifndef CMC_TESTS_UNT_CMC_EQUE_H -#define CMC_TESTS_UNT_CMC_EQUE_H - -#include "utl.h" - -#include "tst_cmc_deque.h" - -struct deque_fval *d_fval = &(struct deque_fval){ - .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp -}; - -struct deque_fval *d_fval_counter = &(struct deque_fval){ - .cmp = v_c_cmp, .cpy = v_c_cpy, .str = v_c_str, .free = v_c_free, .hash = v_c_hash, .pri = v_c_pri -}; - -struct cmc_alloc_node *d_alloc_node = - &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free }; - -CMC_CREATE_UNIT(CMCDeque, true, { - CMC_CREATE_TEST(PFX##_new(), { - struct deque *d = d_new(1000000, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - cmc_assert_not_equals(ptr, NULL, d->buffer); - cmc_assert_equals(size_t, 1000000, d->capacity); - cmc_assert_equals(size_t, 0, d->count); - cmc_assert_equals(size_t, 0, d->front); - cmc_assert_equals(size_t, 0, d->back); - cmc_assert_equals(int32_t, CMC_FLAG_OK, d->flag); - cmc_assert_equals(ptr, d_fval, d->f_val); - cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, d->alloc->malloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, d->alloc->calloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, d->alloc->realloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.free, d->alloc->free); - cmc_assert_equals(ptr, NULL, d->callbacks); - - d_free(d); - - d = d_new(0, d_fval); - cmc_assert_equals(ptr, NULL, d); - - d = d_new(1000, NULL); - cmc_assert_equals(ptr, NULL, d); - - d = d_new(UINT64_MAX, d_fval); - cmc_assert_equals(ptr, NULL, d); - }); - - CMC_CREATE_TEST(PFX##_new_custom(), { - struct deque *d = d_new_custom(1000000, d_fval, d_alloc_node, callbacks); - - cmc_assert_not_equals(ptr, NULL, d); - cmc_assert_not_equals(ptr, NULL, d->buffer); - cmc_assert_equals(size_t, 1000000, d->capacity); - cmc_assert_equals(size_t, 0, d->count); - cmc_assert_equals(size_t, 0, d->front); - cmc_assert_equals(size_t, 0, d->back); - cmc_assert_equals(int32_t, CMC_FLAG_OK, d->flag); - cmc_assert_equals(ptr, d_fval, d->f_val); - cmc_assert_equals(ptr, d_alloc_node, d->alloc); - cmc_assert_equals(ptr, callbacks, d->callbacks); - - d_free(d); - - d = d_new_custom(0, d_fval, d_alloc_node, callbacks); - cmc_assert_equals(ptr, NULL, d); - - d = d_new_custom(1000, NULL, d_alloc_node, callbacks); - cmc_assert_equals(ptr, NULL, d); - - d = d_new_custom(UINT64_MAX, d_fval, d_alloc_node, callbacks); - cmc_assert_equals(ptr, NULL, d); - }); - - CMC_CREATE_TEST(PFX##_init(), { - struct deque d = d_init(1000000, d_fval); - - cmc_assert_not_equals(ptr, NULL, d.buffer); - cmc_assert_equals(size_t, 1000000, d.capacity); - cmc_assert_equals(size_t, 0, d.count); - cmc_assert_equals(size_t, 0, d.front); - cmc_assert_equals(size_t, 0, d.back); - cmc_assert_equals(int32_t, CMC_FLAG_OK, d.flag); - cmc_assert_equals(ptr, d_fval, d.f_val); - cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, d.alloc->malloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, d.alloc->calloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, d.alloc->realloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.free, d.alloc->free); - cmc_assert_equals(ptr, NULL, d.callbacks); - - d_release(d); - - d = d_init(0, d_fval); - - cmc_assert_equals(size_t, 0, d.capacity); - cmc_assert_equals(ptr, NULL, d.buffer); - - d = d_init(1000, NULL); - - cmc_assert_equals(size_t, 0, d.capacity); - cmc_assert_equals(ptr, NULL, d.buffer); - - d = d_init(UINT64_MAX, d_fval); - - cmc_assert_equals(size_t, 0, d.capacity); - cmc_assert_equals(ptr, NULL, d.buffer); - - if (d.buffer) - d_release(d); - }); - - CMC_CREATE_TEST(PFX##_init_custom(), { - struct deque d = d_init_custom(1000000, d_fval, d_alloc_node, callbacks); - - cmc_assert_not_equals(ptr, NULL, d.buffer); - cmc_assert_equals(size_t, 1000000, d.capacity); - cmc_assert_equals(size_t, 0, d.count); - cmc_assert_equals(size_t, 0, d.front); - cmc_assert_equals(size_t, 0, d.back); - cmc_assert_equals(int32_t, CMC_FLAG_OK, d.flag); - cmc_assert_equals(ptr, d_fval, d.f_val); - cmc_assert_equals(ptr, d_alloc_node, d.alloc); - cmc_assert_equals(ptr, callbacks, d.callbacks); - - d_release(d); - - d = d_init_custom(0, d_fval, d_alloc_node, callbacks); - - cmc_assert_equals(size_t, 0, d.capacity); - cmc_assert_equals(ptr, NULL, d.buffer); - - d = d_init_custom(1000, NULL, d_alloc_node, callbacks); - - cmc_assert_equals(size_t, 0, d.capacity); - cmc_assert_equals(ptr, NULL, d.buffer); - - d = d_init_custom(UINT64_MAX, d_fval, d_alloc_node, callbacks); - - cmc_assert_equals(size_t, 0, d.capacity); - cmc_assert_equals(ptr, NULL, d.buffer); - - if (d.buffer) - d_release(d); - }); - - CMC_CREATE_TEST(PFX##_clear(), { - v_total_free = 0; - struct deque *d = d_new(100, d_fval_counter); - - cmc_assert_not_equals(ptr, NULL, d); - - for (size_t i = 0; i < 50; i++) - d_push_back(d, i); - - cmc_assert_equals(size_t, 50, d_count(d)); - - d->flag = CMC_FLAG_ERROR; - d_clear(d); - - cmc_assert_equals(size_t, 50, v_total_free); - cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); - - cmc_assert_equals(size_t, 0, d_count(d)); - cmc_assert_equals(size_t, 100, d_capacity(d)); - - for (size_t i = 1; i <= 1000; i++) - { - if (i % 2 == 0) - d_push_front(d, i); - else - d_push_back(d, i); - } - - cmc_assert_equals(size_t, 1000, d_count(d)); - - size_t sum = 0; - for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++) - sum += d->buffer[i]; - - cmc_assert_equals(size_t, 500500, sum); - - d->flag = CMC_FLAG_ERROR; - d_clear(d); - - cmc_assert_equals(size_t, 1050, v_total_free); - cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); - - sum = 0; - for (size_t i = 0; i < d->capacity; i++) - sum += d->buffer[i]; - - cmc_assert_equals(size_t, 0, sum); - - d_free(d); - - cmc_assert_equals(size_t, 1050, v_total_free); - - v_total_free = 0; - }); - - CMC_CREATE_TEST(PFX##_free(), { - v_total_free = 0; - - struct deque *d = d_new(100, d_fval_counter); - - cmc_assert_not_equals(ptr, NULL, d); - - for (size_t i = 1; i <= 1000; i++) - { - if (i % 2 == 0) - d_push_front(d, i); - else - d_push_back(d, i); - } - - cmc_assert_equals(size_t, 1000, d_count(d)); - - size_t sum = 0; - for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++) - sum += d->buffer[i]; - - cmc_assert_equals(size_t, 500500, sum); - - d_free(d); - - cmc_assert_equals(size_t, 1000, v_total_free); - - v_total_free = 0; - }); - - CMC_CREATE_TEST(PFX##_release(), { - v_total_free = 0; - - struct deque d = d_init(100, d_fval_counter); - - cmc_assert_not_equals(ptr, NULL, d.buffer); - - for (size_t i = 1; i <= 1000; i++) - { - if (i % 2 == 0) - d_push_front(&d, i); - else - d_push_back(&d, i); - } - - cmc_assert_equals(size_t, 1000, d_count(&d)); - - size_t sum = 0; - for (size_t i = d.front, j = 0; j < d.count; i = (i + 1) % d.capacity, j++) - sum += d.buffer[i]; - - cmc_assert_equals(size_t, 500500, sum); - - d_release(d); - - cmc_assert_equals(size_t, 1000, v_total_free); - - v_total_free = 0; - }); - - CMC_CREATE_TEST(PFX##_customize(), { - struct deque *d = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - - d->flag = CMC_FLAG_ERROR; - d_customize(d, d_alloc_node, callbacks); - - cmc_assert_equals(ptr, d_alloc_node, d->alloc); - cmc_assert_equals(ptr, callbacks, d->callbacks); - cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); - - d->flag = CMC_FLAG_ERROR; - d_customize(d, NULL, NULL); - - cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, d->alloc->malloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, d->alloc->calloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, d->alloc->realloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.free, d->alloc->free); - cmc_assert_equals(ptr, NULL, d->callbacks); - cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); - - d_free(d); - }); - - CMC_CREATE_TEST(PFX##_push_front(), { - total_create = 0; - struct deque *d = d_new_custom(100, d_fval, NULL, callbacks); - - cmc_assert_not_equals(ptr, NULL, d); - - d->flag = CMC_FLAG_ERROR; - cmc_assert(d_push_front(d, 10)); - - cmc_assert_equals(size_t, 1, d_count(d)); - cmc_assert_equals(int32_t, 1, total_create); - cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); - - d_customize(d, NULL, NULL); - - d_clear(d); - - for (size_t i = 0; i < 150; i++) - d_push_front(d, i); - - cmc_assert_equals(size_t, 150, d_count(d)); - cmc_assert_greater(size_t, 100, d_capacity(d)); - - d_free(d); - - d = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - - for (size_t i = 1; i <= 10000; i++) - d_push_front(d, i); - - size_t sum = 0; - - for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++) - { - sum += d->buffer[i]; - } - - cmc_assert_equals(size_t, 50005000, sum); - - d_free(d); - - cmc_assert_equals(int32_t, 1, total_create); - total_create = 0; - }); - - CMC_CREATE_TEST(PFX##_push_back(), { - total_create = 0; - struct deque *d = d_new_custom(100, d_fval, NULL, callbacks); - - cmc_assert_not_equals(ptr, NULL, d); - - d->flag = CMC_FLAG_ERROR; - cmc_assert(d_push_front(d, 10)); - - cmc_assert_equals(size_t, 1, d_count(d)); - cmc_assert_equals(int32_t, 1, total_create); - cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); - - d_customize(d, NULL, NULL); - - d_clear(d); - - for (size_t i = 0; i < 150; i++) - d_push_back(d, i); - - cmc_assert_equals(size_t, 150, d_count(d)); - cmc_assert_greater(size_t, 100, d_capacity(d)); - - d_free(d); - - d = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - - for (size_t i = 1; i <= 10000; i++) - d_push_back(d, i); - - size_t sum = 0; - - for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++) - { - sum += d->buffer[i]; - } - - cmc_assert_equals(size_t, 50005000, sum); - - d_free(d); - - cmc_assert_equals(int32_t, 1, total_create); - total_create = 0; - }); - - CMC_CREATE_TEST(PFX##_pop_front(), { - struct deque *d = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - - cmc_assert(!d_pop_front(d)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d)); - - cmc_assert(d_push_front(d, 10)); - d->flag = CMC_FLAG_ERROR; - cmc_assert(d_pop_front(d)); - - cmc_assert_equals(size_t, 0, d_count(d)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); - - cmc_assert(d_push_back(d, 10)); - cmc_assert(d_pop_front(d)); - - cmc_assert_equals(size_t, 0, d_count(d)); - - d_free(d); - - d = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - - for (size_t i = 1; i <= 20000; i++) - d_push_front(d, i); - - cmc_assert_equals(size_t, 20000, d_count(d)); - - for (size_t i = 0; i < 10000; i++) - d_pop_front(d); - - size_t sum = 0; - - for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++) - { - sum += d->buffer[i]; - } - - cmc_assert_equals(size_t, 50005000, sum); - - d_clear(d); - - for (size_t i = 1; i <= 20000; i++) - d_push_front(d, i); - - cmc_assert_equals(size_t, 20000, d_count(d)); - - for (size_t i = 0; i < 10000; i++) - d_pop_front(d); - - sum = 0; - - for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++) - { - sum += d->buffer[i]; - } - - cmc_assert_equals(size_t, 50005000, sum); - - d_free(d); - }); - - CMC_CREATE_TEST(PFX##_pop_back(), { - struct deque *d = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - - cmc_assert(!d_pop_back(d)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d)); - - cmc_assert(d_push_front(d, 10)); - d->flag = CMC_FLAG_ERROR; - cmc_assert(d_pop_back(d)); - - cmc_assert_equals(size_t, 0, d_count(d)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); - - cmc_assert(d_push_back(d, 10)); - cmc_assert(d_pop_back(d)); - - cmc_assert_equals(size_t, 0, d_count(d)); - - d_free(d); - - d = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - - for (size_t i = 1; i <= 20000; i++) - d_push_back(d, i); - - for (size_t i = 0; i < 10000; i++) - d_pop_back(d); - - size_t sum = 0; - - for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++) - { - sum += d->buffer[i]; - } - - cmc_assert_equals(size_t, 50005000, sum); - - d_clear(d); - - for (size_t i = 1; i <= 20000; i++) - d_push_back(d, i); - - cmc_assert_equals(size_t, 20000, d_count(d)); - - for (size_t i = 0; i < 10000; i++) - d_pop_back(d); - - sum = 0; - - for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++) - { - sum += d->buffer[i]; - } - - cmc_assert_equals(size_t, 50005000, sum); - - d_free(d); - }); - - CMC_CREATE_TEST(PFX##_front(), { - struct deque *d = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - - d_front(d); - - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d)); - - cmc_assert(d_push_front(d, 99)); - d->flag = CMC_FLAG_ERROR; - cmc_assert_equals(size_t, 99, d_front(d)); - - cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); - - cmc_assert(d_push_back(d, 98)); - cmc_assert_equals(size_t, 99, d_front(d)); - cmc_assert(d_pop_front(d)); - cmc_assert_equals(size_t, 98, d_front(d)); - - d_clear(d); - - cmc_assert(d_push_back(d, 99)); - cmc_assert_equals(size_t, 99, d_front(d)); - - d_clear(d); - - cmc_assert_equals(size_t, 0, d_count(d)); - - for (size_t i = 1; i <= 10000; i++) - { - if (i % 2 == 0) - d_push_front(d, i); - else - d_push_back(d, i); - } - - size_t sum = 0; - for (size_t i = 0; i < 5000; i++) - { - sum += d_front(d); - cmc_assert_equals(int32_t, 0, d_front(d) % 2); - d_pop_front(d); - } - - cmc_assert_equals(size_t, 5000, d_count(d)); - cmc_assert_equals(size_t, 25005000, sum); - - d_clear(d); - - d_free(d); - }); - - CMC_CREATE_TEST(PFX##_back(), { - struct deque *d = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - - d_back(d); - - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d)); - - cmc_assert(d_push_back(d, 99)); - d->flag = CMC_FLAG_ERROR; - cmc_assert_equals(size_t, 99, d_back(d)); - - cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); - - cmc_assert(d_push_front(d, 98)); - cmc_assert_equals(size_t, 99, d_back(d)); - cmc_assert(d_pop_back(d)); - cmc_assert_equals(size_t, 98, d_back(d)); - - d_clear(d); - - cmc_assert(d_push_front(d, 99)); - cmc_assert_equals(size_t, 99, d_back(d)); - - d_clear(d); - - cmc_assert_equals(size_t, 0, d_count(d)); - - for (size_t i = 1; i <= 10000; i++) - { - if (i % 2 == 0) - d_push_back(d, i); - else - d_push_front(d, i); - } - - size_t sum = 0; - for (size_t i = 0; i < 5000; i++) - { - sum += d_back(d); - cmc_assert_equals(int32_t, 0, d_back(d) % 2); - d_pop_back(d); - } - - cmc_assert_equals(size_t, 5000, d_count(d)); - cmc_assert_equals(size_t, 25005000, sum); - - d_free(d); - }); - - CMC_CREATE_TEST(PFX##_contains(), { - struct deque *d = d_new(100, d_fval); - - for (size_t i = 0; i < 100; i++) - { - if (i % 2 == 0) - d_push_back(d, i); - else - d_push_front(d, i); - } - - for (size_t i = 0; i < 100; i++) - cmc_assert(d_contains(d, i)); - - d_free(d); - - d = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - - for (size_t i = 1; i <= 20; i++) - d_push_back(d, i); - - for (size_t i = 1; i <= 20; i++) - cmc_assert(d_contains(d, i)); - - d_clear(d); - - for (size_t i = 1; i <= 20; i++) - d_push_front(d, i); - - for (size_t i = 1; i <= 20; i++) - cmc_assert(d_contains(d, i)); - - d_free(d); - - d = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - - cmc_assert(!d_contains(d, 10)); - - d_free(d); - - d = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - - cmc_assert(!d_contains(d, 10)); - - cmc_assert(d_push_back(d, 100)); - - cmc_assert(d_contains(d, 100)); - cmc_assert(!d_contains(d, 101)); - - cmc_assert(d_pop_front(d)); - cmc_assert(d_push_front(d, 100)); - - cmc_assert(d_contains(d, 100)); - cmc_assert(!d_contains(d, 101)); - - d_free(d); - }); - - CMC_CREATE_TEST(PFX##_empty(), { - struct deque *d = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - - cmc_assert(d_empty(d)); - - cmc_assert(d_push_back(d, 1)); - - cmc_assert(!d_empty(d)); - - cmc_assert(d_pop_front(d)); - - cmc_assert(d_empty(d)); - - cmc_assert(d_push_front(d, 1)); - - cmc_assert(!d_empty(d)); - - cmc_assert(d_pop_back(d)); - - cmc_assert(d_empty(d)); - - d_free(d); - }); - - CMC_CREATE_TEST(PFX##_full(), { - struct deque *d = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - - cmc_assert(!d_full(d)); - - for (size_t i = 0; i != d_capacity(d); i++) - d_push_front(d, i); - - cmc_assert(d_full(d)); - - d_free(d); - }); - - CMC_CREATE_TEST(PFX##_count(), { - struct deque *d = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - - cmc_assert_equals(size_t, 0, d_count(d)); - - for (size_t i = 0; i < 100; i++) - d_push_back(d, i); - - cmc_assert_equals(size_t, 100, d_count(d)); - - d_free(d); - }); - - CMC_CREATE_TEST(PFX##_capacity(), { - struct deque *d = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - - cmc_assert_equals(size_t, 100, d_capacity(d)); - - d_free(d); - }); - - CMC_CREATE_TEST(PFX##_resize(), { - total_resize = 0; - struct deque *d = d_new_custom(100, d_fval, NULL, callbacks); - - cmc_assert_not_equals(ptr, NULL, d); - - cmc_assert_equals(size_t, 100, d_capacity(d)); - d->flag = CMC_FLAG_ERROR; - cmc_assert(d_resize(d, 100)); - cmc_assert_equals(size_t, 100, d_capacity(d)); - - cmc_assert_equals(int32_t, 1, total_resize); - - cmc_assert(d_resize(d, 200)); - cmc_assert_equals(size_t, 200, d_capacity(d)); - - cmc_assert(d_resize(d, 100)); - cmc_assert_equals(size_t, 100, d_capacity(d)); - - cmc_assert_equals(int32_t, 3, total_resize); - - for (size_t i = 0; i < 150; i++) - { - if (i % 2 == 0) - cmc_assert(d_push_back(d, i)); - else - cmc_assert(d_push_front(d, i)); - } - - cmc_assert_equals(size_t, 150, d_count(d)); - cmc_assert(d_resize(d, d_count(d))); - cmc_assert_equals(size_t, 150, d_capacity(d)); - - cmc_assert(!d_resize(d, d_count(d) - 10)); - cmc_assert_equals(int32_t, CMC_FLAG_INVALID, d_flag(d)); - - d_free(d); - - // item preservation - d = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - - for (size_t i = 1; i <= 150; i++) - { - if (i % 2 != 0) - cmc_assert(d_push_back(d, i)); - else - cmc_assert(d_push_front(d, i)); - } - - cmc_assert(d_resize(d, d_count(d))); - - size_t sum = 0; - - for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++) - { - sum += d->buffer[i]; - } - - cmc_assert_equals(size_t, 11325, sum); - - d_free(d); - total_resize = 0; - }); - - CMC_CREATE_TEST(PFX##_copy_of(), { - v_total_cpy = 0; - struct deque *d1 = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d1); - - for (size_t i = 1; i <= 150; i++) - { - if (i % 2 != 0) - d_push_back(d1, i); - else - d_push_front(d1, i); - } - - struct deque *d2 = d_copy_of(d1); - - cmc_assert_not_equals(ptr, NULL, d2); - cmc_assert_equals(size_t, d_count(d1), d_count(d2)); - - for (size_t i1 = d1->front, i2 = d2->front, j = 0; j < d1->count; j++) - { - cmc_assert_equals(size_t, d1->buffer[i1], d2->buffer[i2]); - - i1 = (i1 + 1) % d1->capacity; - i2 = (i2 + 1) % d2->capacity; - } - - cmc_assert(d_push_front(d1, 10)); - cmc_assert(d_push_front(d2, 10)); - cmc_assert(d_push_back(d1, 11)); - cmc_assert(d_push_back(d2, 11)); - - cmc_assert(d_equals(d1, d2)); - - d_free(d1); - d_free(d2); - - // v_total_cpy - d1 = d_new_custom(100, d_fval_counter, d_alloc_node, NULL); - - cmc_assert_not_equals(ptr, NULL, d1); - - d2 = d_copy_of(d1); - - cmc_assert_not_equals(ptr, NULL, d1); - - cmc_assert_equals(int32_t, 0, v_total_cpy); - - d_free(d2); - - for (size_t i = 0; i < 1000; i++) - { - if (i % 2 != 0) - d_push_back(d1, i); - else - d_push_front(d1, i); - } - - cmc_assert_equals(size_t, 1000, d1->count); - - d2 = d_copy_of(d1); - - cmc_assert_equals(int32_t, 1000, v_total_cpy); - - d_free(d1); - d_free(d2); - v_total_cpy = 0; - }); - - CMC_CREATE_TEST(PFX##_equals(), { - v_total_cmp = 0; - struct deque *d1 = d_new(100, d_fval); - struct deque *d2 = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d1); - cmc_assert_not_equals(ptr, NULL, d2); - - for (size_t i = 1; i <= 150; i++) - { - if (i % 2 != 0) - { - d_push_back(d1, i); - d_push_back(d2, i); - } - else - { - d_push_front(d1, i); - d_push_front(d2, i); - } - } - - cmc_assert(d_equals(d1, d2)); - - d_free(d1); - d_free(d2); - - // from copy - d1 = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d1); - - for (size_t i = 1; i <= 150; i++) - { - if (i % 2 != 0) - cmc_assert(d_push_back(d1, i)); - else - cmc_assert(d_push_front(d1, i)); - } - - d2 = d_copy_of(d1); - - cmc_assert_not_equals(ptr, NULL, d2); - - cmc_assert(d_equals(d1, d2)); - - d_free(d1); - d_free(d2); - - // count = 0 - d1 = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d1); - - d2 = d_copy_of(d1); - - cmc_assert_not_equals(ptr, NULL, d2); - - cmc_assert(d_equals(d1, d2)); - - d_free(d1); - d_free(d2); - - // false eq - d1 = d_new(100, d_fval); - d2 = d_new_custom(100, d_fval_counter, d_alloc_node, NULL); - - cmc_assert(d_equals(d1, d2)); - - cmc_assert_equals(int32_t, 0, v_total_cmp); - - d_push_back(d1, 100); - - cmc_assert(!d_equals(d1, d2)); - - d_push_back(d2, 100); - - cmc_assert(d_equals(d1, d2)); - - d_push_front(d1, 10); - d_push_front(d2, 10); - - cmc_assert(d_equals(d1, d2)); - - d_push_back(d1, 40); - d_push_back(d2, 41); - - cmc_assert(!d_equals(d1, d2)); - - v_total_cmp = 0; - - d_clear(d1); - d_clear(d2); - - for (size_t i = 0; i < 1000; i++) - { - if (i % 2 == 0) - { - d_push_back(d1, i); - d_push_back(d2, i); - } - else - { - d_push_front(d1, i); - d_push_front(d2, i); - } - } - - // d2's cmp is used and v_total_cmp is incremented each time - cmc_assert(d_equals(d2, d1)); - - cmc_assert_equals(int32_t, 1000, v_total_cmp); - - d_free(d1); - d_free(d2); - v_total_cmp = 0; - }); - - CMC_CREATE_TEST(Mixed IO, { - struct deque *d = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - - cmc_assert(d_push_front(d, 10)); - cmc_assert(d_push_front(d, 10)); - cmc_assert(d_pop_back(d)); - cmc_assert(d_pop_back(d)); - - cmc_assert_equals(size_t, 0, d_count(d)); - - cmc_assert(d_push_back(d, 10)); - cmc_assert(d_push_back(d, 10)); - cmc_assert(d_pop_back(d)); - cmc_assert(d_pop_back(d)); - - cmc_assert_equals(size_t, 0, d_count(d)); - - cmc_assert(d_push_front(d, 10)); - cmc_assert(d_push_front(d, 10)); - cmc_assert(d_pop_front(d)); - cmc_assert(d_pop_front(d)); - - cmc_assert_equals(size_t, 0, d_count(d)); - - cmc_assert(d_push_back(d, 10)); - cmc_assert(d_push_back(d, 10)); - cmc_assert(d_pop_front(d)); - cmc_assert(d_pop_front(d)); - - cmc_assert_equals(size_t, 0, d_count(d)); - // ---------- - cmc_assert(d_push_back(d, 10)); - cmc_assert(d_push_front(d, 10)); - cmc_assert(d_pop_back(d)); - cmc_assert(d_pop_front(d)); - - cmc_assert_equals(size_t, 0, d_count(d)); - - cmc_assert(d_push_back(d, 10)); - cmc_assert(d_push_front(d, 10)); - cmc_assert(d_pop_front(d)); - cmc_assert(d_pop_back(d)); - - cmc_assert_equals(size_t, 0, d_count(d)); - - cmc_assert(d_push_front(d, 10)); - cmc_assert(d_push_back(d, 10)); - cmc_assert(d_pop_back(d)); - cmc_assert(d_pop_front(d)); - - cmc_assert_equals(size_t, 0, d_count(d)); - - cmc_assert(d_push_front(d, 10)); - cmc_assert(d_push_back(d, 10)); - cmc_assert(d_pop_front(d)); - cmc_assert(d_pop_back(d)); - - cmc_assert_equals(size_t, 0, d_count(d)); - - d_free(d); - }); - - CMC_CREATE_TEST(buffer_growth[capacity = 1], { - struct deque *d = d_new(1, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - - for (size_t i = 0; i < 50; i++) - d_push_back(d, i); - - cmc_assert_equals(size_t, 50, d_count(d)); - cmc_assert_lesser_equals(size_t, d_capacity(d), d_count(d)); - - d_free(d); - }); - - CMC_CREATE_TEST(buffer_growth[item preservation], { - struct deque *d = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - - for (size_t i = 1; i <= 1200; i++) - { - if (i % 2 == 0) - d_push_front(d, i); - else - d_push_back(d, i); - } - - size_t sum = 0; - for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++) - sum += d->buffer[i]; - - cmc_assert_equals(size_t, 1200, d_count(d)); - cmc_assert_equals(size_t, 720600, sum); - - d_free(d); - }); - - CMC_CREATE_TEST(flags, { - struct deque *d = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); - - // customize - d->flag = CMC_FLAG_ERROR; - d_customize(d, &cmc_alloc_node_default, &(struct cmc_callbacks){ 0 }); - cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); - - // push_front - d->flag = CMC_FLAG_ERROR; - cmc_assert(d_push_front(d, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); - - // pop_front - d->flag = CMC_FLAG_ERROR; - cmc_assert(d_pop_front(d)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); - cmc_assert(!d_pop_front(d)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d)); - - // push_back - cmc_assert(d_push_back(d, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); - - // pop_back - d->flag = CMC_FLAG_ERROR; - cmc_assert(d_pop_back(d)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); - cmc_assert(!d_pop_back(d)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d)); - - // front - d->flag = CMC_FLAG_ERROR; - cmc_assert(d_front(d) == 0); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d)); - - cmc_assert(d_push_back(d, 1)); - d->flag = CMC_FLAG_ERROR; - cmc_assert(d_front(d) == 1); - cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); - - // clear - d->flag = CMC_FLAG_ERROR; - d_clear(d); - cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); - - // back - cmc_assert(d_back(d) == 0); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d)); - - cmc_assert(d_push_front(d, 1)); - cmc_assert(d_back(d) == 1); - cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); - - // contains - d->flag = CMC_FLAG_ERROR; - cmc_assert(d_contains(d, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); - - // copy_of - d->flag = CMC_FLAG_ERROR; - struct deque *d2 = d_copy_of(d); - cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d2)); - - // equals - cmc_assert(d_pop_back(d)); - cmc_assert(d_pop_back(d2)); - d->flag = CMC_FLAG_ERROR; - d2->flag = CMC_FLAG_ERROR; - d_front(d); - d_front(d2); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d2)); - cmc_assert(d_equals(d, d2)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d2)); - - d_free(d); - d_free(d2); - }); - - CMC_CREATE_TEST(callbacks, { - struct deque *d = d_new_custom(100, d_fval, NULL, callbacks); - - total_create = 0; - total_read = 0; - total_update = 0; - total_delete = 0; - total_resize = 0; - - cmc_assert(d_push_front(d, 10)); - cmc_assert_equals(int32_t, 1, total_create); - - cmc_assert(d_push_back(d, 10)); - cmc_assert_equals(int32_t, 2, total_create); - - cmc_assert(d_pop_front(d)); - cmc_assert_equals(int32_t, 1, total_delete); - - cmc_assert(d_pop_back(d)); - cmc_assert_equals(int32_t, 2, total_delete); - - cmc_assert(d_push_front(d, 10)); - cmc_assert(d_push_front(d, 5)); - cmc_assert_equals(int32_t, 4, total_create); - - cmc_assert_equals(size_t, 5, d_front(d)); - cmc_assert_equals(int32_t, 1, total_read); - - cmc_assert_equals(size_t, 10, d_back(d)); - cmc_assert_equals(int32_t, 2, total_read); - - cmc_assert(d_contains(d, 10)); - cmc_assert(!d_contains(d, 1)); - cmc_assert_equals(int32_t, 4, total_read); - - cmc_assert(d_resize(d, 1000)); - cmc_assert_equals(int32_t, 1, total_resize); - - cmc_assert(d_resize(d, 10)); - cmc_assert_equals(int32_t, 2, total_resize); - - cmc_assert_equals(int32_t, 4, total_create); - cmc_assert_equals(int32_t, 4, total_read); - cmc_assert_equals(int32_t, 0, total_update); - cmc_assert_equals(int32_t, 2, total_delete); - cmc_assert_equals(int32_t, 2, total_resize); - - d_customize(d, NULL, NULL); - - cmc_assert_equals(ptr, NULL, d->callbacks); - - d_clear(d); - cmc_assert(d_push_front(d, 10)); - cmc_assert(d_push_back(d, 10)); - cmc_assert(d_pop_front(d)); - cmc_assert(d_pop_back(d)); - cmc_assert(d_push_front(d, 10)); - cmc_assert(d_push_front(d, 5)); - cmc_assert_equals(size_t, 5, d_front(d)); - cmc_assert_equals(size_t, 10, d_back(d)); - cmc_assert(d_contains(d, 10)); - cmc_assert(!d_contains(d, 1)); - cmc_assert(d_resize(d, 1000)); - cmc_assert(d_resize(d, 10)); - - cmc_assert_equals(int32_t, 4, total_create); - cmc_assert_equals(int32_t, 4, total_read); - cmc_assert_equals(int32_t, 0, total_update); - cmc_assert_equals(int32_t, 2, total_delete); - cmc_assert_equals(int32_t, 2, total_resize); - - cmc_assert_equals(ptr, NULL, d->callbacks); - - d_free(d); - - total_create = 0; - total_read = 0; - total_update = 0; - total_delete = 0; - total_resize = 0; - }); -}); - -CMC_CREATE_UNIT(CMCDequeIter, true, { - CMC_CREATE_TEST(PFX##_iter_start(), { - struct deque *d = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - - struct deque_iter it = d_iter_start(d); - - cmc_assert_equals(ptr, d, it.target); - cmc_assert_equals(size_t, d->front, it.cursor); - cmc_assert_equals(size_t, 0, it.index); - cmc_assert_equals(bool, true, it.start); - cmc_assert_equals(bool, true, it.end); - - cmc_assert(d_iter_at_start(&it)); - cmc_assert(d_iter_at_end(&it)); - - cmc_assert(d_push_front(d, 1)); - cmc_assert(d_push_front(d, 2)); - - it = d_iter_start(d); - - cmc_assert_equals(size_t, 0, it.index); - cmc_assert_equals(bool, false, it.end); - cmc_assert_equals(size_t, d->front, it.cursor); - - d_free(d); - }); - - CMC_CREATE_TEST(PFX##_iter_end(), { - struct deque *d = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - - struct deque_iter it = d_iter_end(d); - - cmc_assert_equals(ptr, d, it.target); - cmc_assert_equals(size_t, d->back, it.cursor); - cmc_assert_equals(size_t, 0, it.index); - cmc_assert_equals(bool, true, it.start); - cmc_assert_equals(bool, true, it.end); - - cmc_assert(d_iter_at_start(&it)); - cmc_assert(d_iter_at_end(&it)); - - cmc_assert(d_push_back(d, 1)); - cmc_assert(d_push_back(d, 2)); - cmc_assert(d_push_back(d, 3)); - - it = d_iter_end(d); - - cmc_assert_equals(size_t, d->count - 1, it.index); - cmc_assert_equals(size_t, d->back - 1, it.cursor); - cmc_assert_equals(bool, false, it.start); - - d_free(d); - }); - - CMC_CREATE_TEST(PFX##_iter_at_start(), { - struct deque *d = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - - struct deque_iter it = d_iter_start(d); - - // Empty checks - cmc_assert(d_iter_at_start(&it)); - it = d_iter_end(d); - cmc_assert(d_iter_at_start(&it)); - - // Non-empty checks - cmc_assert(d_push_back(d, 1)); - it = d_iter_end(d); - cmc_assert(!d_iter_at_start(&it)); - it = d_iter_start(d); - cmc_assert(d_iter_at_start(&it)); - - d_clear(d); - - cmc_assert(d_push_front(d, 1)); - it = d_iter_end(d); - cmc_assert(!d_iter_at_start(&it)); - it = d_iter_start(d); - cmc_assert(d_iter_at_start(&it)); - - d_free(d); - }); - - CMC_CREATE_TEST(PFX##_iter_at_end(), { - struct deque *d = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - - struct deque_iter it = d_iter_start(d); - - // Empty check - cmc_assert(d_iter_at_end(&it)); - it = d_iter_end(d); - cmc_assert(d_iter_at_end(&it)); - - // Non-empty checks - cmc_assert(d_push_back(d, 1)); - it = d_iter_end(d); - cmc_assert(d_iter_at_end(&it)); - it = d_iter_start(d); - cmc_assert(!d_iter_at_end(&it)); - - d_clear(d); - - cmc_assert(d_push_front(d, 1)); - it = d_iter_end(d); - cmc_assert(d_iter_at_end(&it)); - it = d_iter_start(d); - cmc_assert(!d_iter_at_end(&it)); - - d_free(d); - }); - - CMC_CREATE_TEST(PFX##_iter_to_start(), { - struct deque *d = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - - struct deque_iter it = d_iter_start(d); - - cmc_assert(!d_iter_to_start(&it)); - - for (size_t i = 1; i <= 100; i++) - { - if (i % 2 == 0) - d_push_back(d, i); - else - d_push_front(d, i); - } - - cmc_assert_equals(size_t, 100, d->count); - - it = d_iter_end(d); - - cmc_assert(!d_iter_at_start(&it)); - cmc_assert(d_iter_at_end(&it)); - - cmc_assert_equals(size_t, 100, d_iter_value(&it)); - - cmc_assert(d_iter_to_start(&it)); - - cmc_assert(d_iter_at_start(&it)); - cmc_assert(!d_iter_at_end(&it)); - - cmc_assert_equals(size_t, 99, d_iter_value(&it)); - - d_free(d); - }); - - CMC_CREATE_TEST(PFX##_iter_to_end(), { - struct deque *d = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - - struct deque_iter it = d_iter_end(d); - - cmc_assert(!d_iter_to_end(&it)); - - for (size_t i = 1; i <= 100; i++) - { - if (i % 2 == 0) - d_push_back(d, i); - else - d_push_front(d, i); - } - - it = d_iter_start(d); - - cmc_assert(d_iter_at_start(&it)); - cmc_assert(!d_iter_at_end(&it)); - - cmc_assert_equals(size_t, 99, d_iter_value(&it)); - - cmc_assert(d_iter_to_end(&it)); - - cmc_assert(!d_iter_at_start(&it)); - cmc_assert(d_iter_at_end(&it)); - - cmc_assert_equals(size_t, 100, d_iter_value(&it)); - - d_free(d); - }); - - CMC_CREATE_TEST(PFX##_iter_next(), { - struct deque *d = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - - struct deque_iter it = d_iter_start(d); - - cmc_assert(!d_iter_next(&it)); - - for (size_t i = 1; i <= 1000; i++) - { - if (i % 2 == 0) - d_push_back(d, i); - else - d_push_front(d, i); - } - - size_t sum = 0; - for (it = d_iter_start(d); !d_iter_at_end(&it); d_iter_next(&it)) - { - sum += d_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - - d_iter_to_start(&it); - do - { - sum += d_iter_value(&it); - } while (d_iter_next(&it)); - - cmc_assert_equals(size_t, 500500, sum); - - d_free(d); - }); - - CMC_CREATE_TEST(PFX##_iter_prev(), { - struct deque *d = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - - struct deque_iter it = d_iter_end(d); - - cmc_assert(!d_iter_prev(&it)); - - for (size_t i = 1; i <= 1000; i++) - { - if (i % 2 == 0) - d_push_back(d, i); - else - d_push_front(d, i); - } - - size_t sum = 0; - for (it = d_iter_end(d); !d_iter_at_start(&it); d_iter_prev(&it)) - { - sum += d_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - - d_iter_to_end(&it); - do - { - sum += d_iter_value(&it); - } while (d_iter_prev(&it)); - - cmc_assert_equals(size_t, 500500, sum); - - d_free(d); - }); - - CMC_CREATE_TEST(PFX##_iter_advance(), { - struct deque *d = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - - struct deque_iter it = d_iter_start(d); - - cmc_assert(!d_iter_advance(&it, 1)); - - for (size_t i = 0; i <= 1000; i++) - { - if (i % 2 == 0) - d_push_back(d, i); // will sum all even numbers - else - d_push_back(d, 0); - } - - it = d_iter_start(d); - - cmc_assert(!d_iter_advance(&it, 0)); - cmc_assert(!d_iter_advance(&it, d->count)); - - size_t sum = 0; - for (it = d_iter_start(d);;) - { - sum += d_iter_value(&it); - - if (!d_iter_advance(&it, 2)) - break; - } - - cmc_assert_equals(size_t, 250500, sum); - - d_iter_to_start(&it); - cmc_assert(d_iter_advance(&it, d->count - 1)); - - d_free(d); - }); - - CMC_CREATE_TEST(PFX##_iter_rewind(), { - struct deque *d = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - - struct deque_iter it = d_iter_end(d); - - cmc_assert(!d_iter_rewind(&it, 1)); - - for (size_t i = 0; i <= 1000; i++) - { - if (i % 2 == 0) - d_push_front(d, i); // will sum all even numbers - else - d_push_front(d, 0); - } - - it = d_iter_end(d); - - cmc_assert(!d_iter_rewind(&it, 0)); - cmc_assert(!d_iter_rewind(&it, d->count)); - - size_t sum = 0; - for (it = d_iter_end(d);;) - { - sum += d_iter_value(&it); - - if (!d_iter_rewind(&it, 2)) - break; - } - - cmc_assert_equals(size_t, 250500, sum); - - d_iter_to_end(&it); - cmc_assert(d_iter_rewind(&it, d->count - 1)); - - d_free(d); - }); - - CMC_CREATE_TEST(PFX##_iter_go_to(), { - struct deque *d = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - - struct deque_iter it = d_iter_end(d); - cmc_assert(!d_iter_go_to(&it, 0)); - - it = d_iter_start(d); - cmc_assert(!d_iter_go_to(&it, 0)); - - for (size_t i = 0; i <= 1000; i++) - d_push_back(d, i); - - it = d_iter_start(d); - - size_t sum = 0; - for (size_t i = 0; i < 1001; i++) - { - d_iter_go_to(&it, i); - - sum += d_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - for (size_t i = 1001; i > 0; i--) - { - cmc_assert(d_iter_go_to(&it, i - 1)); - - sum += d_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - for (size_t i = 0; i < 1001; i += 100) - { - cmc_assert(d_iter_go_to(&it, i)); - cmc_assert_equals(size_t, i, d_iter_index(&it)); - - sum += d_iter_value(&it); - } - - cmc_assert_equals(size_t, 5500, sum); - - d_free(d); - }); - - CMC_CREATE_TEST(PFX##_iter_value(), { - struct deque *d = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - - struct deque_iter it = d_iter_end(d); - - cmc_assert_equals(size_t, (size_t){ 0 }, d_iter_value(&it)); - - cmc_assert(d_push_back(d, 10)); - - it = d_iter_start(d); - - cmc_assert_equals(size_t, 10, d_iter_value(&it)); - - d_free(d); - }); - - CMC_CREATE_TEST(PFX##_iter_rvalue(), { - struct deque *d = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - - struct deque_iter it = d_iter_end(d); - - cmc_assert_equals(ptr, NULL, d_iter_rvalue(&it)); - - cmc_assert(d_push_back(d, 10)); - - it = d_iter_start(d); - - cmc_assert_not_equals(ptr, NULL, d_iter_rvalue(&it)); - cmc_assert_equals(size_t, 10, *d_iter_rvalue(&it)); - - d_free(d); - }); - - CMC_CREATE_TEST(PFX##_iter_index(), { - struct deque *d = d_new(100, d_fval); - - cmc_assert_not_equals(ptr, NULL, d); - - for (size_t i = 0; i <= 1000; i++) - d_push_back(d, i); - - struct deque_iter it = d_iter_start(d); - - for (size_t i = 0; i < 1001; i++) - { - cmc_assert_equals(size_t, i, d_iter_index(&it)); - d_iter_next(&it); - } - - it = d_iter_end(d); - for (size_t i = 1001; i > 0; i--) - { - cmc_assert_equals(size_t, i - 1, d_iter_index(&it)); - d_iter_prev(&it); - } - - d_free(d); - }); -}); - -#ifdef CMC_TEST_MAIN -int main(void) -{ - int result = CMCDeque() + CMCDequeIter(); - - printf(" +---------------------------------------------------------------+"); - printf("\n"); - printf(" | CMCDeque Suit : %-48s |\n", result == 0 ? "PASSED" : "FAILED"); - printf(" +---------------------------------------------------------------+"); - printf("\n\n\n"); - - return result; -} -#endif - -#endif /* CMC_TESTS_UNT_CMC_EQUE_H */ diff --git a/tests/unt/unt_cmc_hashbidimap.h b/tests/unt/unt_cmc_hashbidimap.h deleted file mode 100644 index ca0f550..0000000 --- a/tests/unt/unt_cmc_hashbidimap.h +++ /dev/null @@ -1,826 +0,0 @@ -#ifndef CMC_TESTS_UNT_CMC_ASHBIDIMAP_H -#define CMC_TESTS_UNT_CMC_ASHBIDIMAP_H - -#include "utl.h" - -#include "tst_cmc_hashbidimap.h" - -struct hashbidimap_fkey *hbm_fkey = &(struct hashbidimap_fkey){ - .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp -}; - -struct hashbidimap_fval *hbm_fval = &(struct hashbidimap_fval){ - .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp -}; - -struct hashbidimap_fkey *hbm_fkey_counter = &(struct hashbidimap_fkey){ - .cmp = k_c_cmp, .cpy = k_c_cpy, .str = k_c_str, .free = k_c_free, .hash = k_c_hash, .pri = k_c_pri -}; - -struct hashbidimap_fval *hbm_fval_counter = &(struct hashbidimap_fval){ - .cmp = v_c_cmp, .cpy = v_c_cpy, .str = v_c_str, .free = v_c_free, .hash = v_c_hash, .pri = v_c_pri -}; - -struct cmc_alloc_node *hbm_alloc_node = - &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free }; - -CMC_CREATE_UNIT(CMCHashBidiMap, true, { - CMC_CREATE_TEST(PFX##_new(), { - struct hashbidimap *map = hbm_new(943722, 0.6, hbm_fkey, hbm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - cmc_assert_not_equals(ptr, NULL, map->buffer); - cmc_assert_equals(size_t, 0, map->count); - cmc_assert_equals(double, 0.6, map->load); - cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag); - cmc_assert_equals(ptr, hbm_fkey, map->f_key); - cmc_assert_equals(ptr, hbm_fval, map->f_val); - cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, map->alloc->malloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, map->alloc->calloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, map->alloc->realloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.free, map->alloc->free); - cmc_assert_equals(ptr, NULL, map->callbacks); - - cmc_assert_greater_equals(size_t, (943722 / 0.6), hbm_capacity(map)); - - hbm_free(map); - - map = hbm_new(100, 0.6, hbm_fkey, hbm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 0; i < map->capacity; i++) - { - cmc_assert_equals(ptr, NULL, map->buffer[i][0]); - cmc_assert_equals(ptr, NULL, map->buffer[i][1]); - } - - hbm_free(map); - - map = hbm_new(0, 0.6, hbm_fkey, hbm_fval); - cmc_assert_equals(ptr, NULL, map); - - map = hbm_new(UINT64_MAX, 0.99, hbm_fkey, hbm_fval); - cmc_assert_equals(ptr, NULL, map); - - map = hbm_new(1000, 0.6, hbm_fkey, NULL); - cmc_assert_equals(ptr, NULL, map); - - map = hbm_new(1000, 0.6, NULL, hbm_fval); - cmc_assert_equals(ptr, NULL, map); - - map = hbm_new(1000, 0.6, NULL, NULL); - cmc_assert_equals(ptr, NULL, map); - }); - - CMC_CREATE_TEST(PFX##_new_custom(), { - struct hashbidimap *map = hbm_new_custom(943722, 0.6, hbm_fkey, hbm_fval, hbm_alloc_node, callbacks); - - cmc_assert_not_equals(ptr, NULL, map); - cmc_assert_not_equals(ptr, NULL, map->buffer); - cmc_assert_equals(size_t, 0, map->count); - cmc_assert_equals(double, 0.6, map->load); - cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag); - cmc_assert_equals(ptr, hbm_fkey, map->f_key); - cmc_assert_equals(ptr, hbm_fval, map->f_val); - cmc_assert_equals(ptr, hbm_alloc_node, map->alloc); - cmc_assert_equals(ptr, callbacks, map->callbacks); - - cmc_assert_greater_equals(size_t, (943722 / 0.6), hbm_capacity(map)); - - hbm_free(map); - - map = hbm_new_custom(0, 0.6, hbm_fkey, hbm_fval, NULL, NULL); - cmc_assert_equals(ptr, NULL, map); - - map = hbm_new_custom(UINT64_MAX, 0.99, hbm_fkey, hbm_fval, NULL, NULL); - cmc_assert_equals(ptr, NULL, map); - - map = hbm_new_custom(1000, 0.6, hbm_fkey, NULL, NULL, NULL); - cmc_assert_equals(ptr, NULL, map); - - map = hbm_new_custom(1000, 0.6, NULL, hbm_fval, NULL, NULL); - cmc_assert_equals(ptr, NULL, map); - - map = hbm_new_custom(1000, 0.6, NULL, NULL, NULL, NULL); - cmc_assert_equals(ptr, NULL, map); - }); - - CMC_CREATE_TEST(PFX##_clear(), { - k_total_free = 0; - v_total_free = 0; - struct hashbidimap *map = hbm_new(100, 0.6, hbm_fkey_counter, hbm_fval_counter); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 1; i <= 1000; i++) - hbm_insert(map, i, i); - - cmc_assert_equals(size_t, 1000, map->count); - - map->flag = CMC_FLAG_ERROR; - hbm_clear(map); - - cmc_assert_equals(size_t, 0, map->count); - cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag); - cmc_assert_equals(int32_t, 1000, k_total_free); - cmc_assert_equals(int32_t, 1000, v_total_free); - - hbm_free(map); - k_total_free = 0; - v_total_free = 0; - }); - - CMC_CREATE_TEST(PFX##_free(), { - k_total_free = 0; - v_total_free = 0; - struct hashbidimap *map = hbm_new(100, 0.6, hbm_fkey_counter, hbm_fval_counter); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 1; i <= 1000; i++) - hbm_insert(map, i, i); - - cmc_assert_equals(size_t, 1000, map->count); - - hbm_free(map); - - cmc_assert_equals(int32_t, 1000, k_total_free); - cmc_assert_equals(int32_t, 1000, v_total_free); - - map = hbm_new(1000, 0.6, hbm_fkey_counter, hbm_fval_counter); - - cmc_assert_not_equals(ptr, NULL, map); - cmc_assert_not_equals(ptr, NULL, map->buffer); - - hbm_free(map); - - cmc_assert_equals(int32_t, 1000, k_total_free); - cmc_assert_equals(int32_t, 1000, v_total_free); - k_total_free = 0; - v_total_free = 0; - }); - - CMC_CREATE_TEST(customize, { - struct hashbidimap *map = hbm_new_custom(100, 0.6, hbm_fkey, hbm_fval, NULL, NULL); - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, map->alloc->malloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, map->alloc->calloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, map->alloc->realloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.free, map->alloc->free); - cmc_assert_equals(ptr, NULL, map->callbacks); - - hbm_free(map); - - struct cmc_alloc_node node; - node.malloc = malloc; - node.realloc = realloc; - node.free = free; - node.calloc = calloc; - - map = hbm_new_custom(100, 0.6, hbm_fkey, hbm_fval, &node, callbacks); - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert_equals(ptr, &node, map->alloc); - cmc_assert_equals(ptr, callbacks, map->callbacks); - - hbm_free(map); - }); - - CMC_CREATE_TEST(buffer_growth[capacity = 1], { - struct hashbidimap *map = hbm_new(1, 0.7, hbm_fkey, hbm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 1; i <= 10000; i++) - cmc_assert(hbm_insert(map, i, i)); - - size_t sum = 0; - - for (size_t i = 0; i < hbm_capacity(map); i++) - { - if (map->buffer[i][0] && map->buffer[i][0] != CMC_ENTRY_DELETED) - { - sum += map->buffer[i][0]->key; - } - } - - cmc_assert_equals(size_t, 50005000, sum); - - hbm_free(map); - }); - - CMC_CREATE_TEST(insert, { - struct hashbidimap *map = hbm_new(100, 0.7, hbm_fkey, hbm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert(hbm_insert(map, 1, 1)); - cmc_assert(hbm_insert(map, 2, 2)); - cmc_assert(hbm_insert(map, 3, 3)); - - cmc_assert_equals(size_t, 3, hbm_count(map)); - - hbm_free(map); - }); - - CMC_CREATE_TEST(insert[duplicate], { - struct hashbidimap *map = hbm_new(100, 0.7, hbm_fkey, hbm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert(hbm_insert(map, 1, 1)); - cmc_assert(!hbm_insert(map, 1, 1)); - cmc_assert(!hbm_insert(map, 2, 1)); - cmc_assert(!hbm_insert(map, 1, 2)); - cmc_assert(hbm_insert(map, 2, 2)); - - cmc_assert_equals(size_t, 2, hbm_count(map)); - - hbm_free(map); - }); - - CMC_CREATE_TEST(insert[references], { - struct hashbidimap *map = hbm_new(500, 0.7, hbm_fkey, hbm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 0; i < 500; i++) - cmc_assert(hbm_insert(map, i, i)); - - for (size_t i = 0; i < map->capacity; i++) - { - struct hashbidimap_entry *kentry = map->buffer[i][0]; - struct hashbidimap_entry *ventry = map->buffer[i][1]; - - if (kentry && kentry != CMC_ENTRY_DELETED) - cmc_assert_equals(ptr, kentry, *(kentry->ref[0])); - if (ventry && ventry != CMC_ENTRY_DELETED) - cmc_assert_equals(ptr, ventry, *(ventry->ref[1])); - } - - hbm_free(map); - }); - - CMC_CREATE_TEST(insert[growth remove clear], { - struct hashbidimap *map = hbm_new(100, 0.7, hbm_fkey, hbm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 1; i <= 1000; i++) - cmc_assert(hbm_insert(map, i, i)); - - cmc_assert_equals(size_t, 1000, hbm_count(map)); - - size_t j = 1; - while (!hbm_empty(map)) - { - if (hbm_count(map) % 2 == 0) - cmc_assert(hbm_remove_by_key(map, j++, NULL, NULL)); - else - cmc_assert(hbm_remove_by_val(map, j++, NULL, NULL)); - } - - cmc_assert_equals(size_t, 0, hbm_count(map)); - - for (size_t i = 1; i <= 1000; i++) - cmc_assert(hbm_insert(map, i, i)); - - cmc_assert_equals(size_t, 1000, hbm_count(map)); - - hbm_clear(map); - - cmc_assert_equals(size_t, 0, hbm_count(map)); - - hbm_free(map); - }); - - CMC_CREATE_TEST(insert[ftab hash calls], { - struct hashbidimap *map = hbm_new(100, 0.7, hbm_fkey_counter, hbm_fval_counter); - - cmc_assert_not_equals(ptr, NULL, map); - - k_total_hash = 0; - v_total_hash = 0; - - for (size_t i = 1; i <= 1000; i++) - cmc_assert(hbm_insert(map, i, i)); - - cmc_assert_greater_equals(int32_t, 1000, k_total_hash); - cmc_assert_greater_equals(int32_t, 1000, v_total_hash); - - hbm_free(map); - - k_total_hash = 0; - v_total_hash = 0; - }); - - CMC_CREATE_TEST(update_key, { - struct hashbidimap *map = hbm_new(100, 0.7, hbm_fkey, hbm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 1; i <= 100; i++) - cmc_assert(hbm_insert(map, i, i)); - - cmc_assert_equals(size_t, 100, hbm_count(map)); - - for (size_t i = 100; i > 0; i--) - cmc_assert(hbm_update_key(map, i, i + 10)); - - cmc_assert_equals(size_t, 100, hbm_count(map)); - - for (size_t i = 1; i <= 100; i++) - cmc_assert_equals(size_t, i + 10, hbm_get_key(map, i)); - - cmc_assert_equals(size_t, 100, hbm_count(map)); - - hbm_free(map); - }); - - CMC_CREATE_TEST(update_key[empty], { - struct hashbidimap *map = hbm_new(100, 0.7, hbm_fkey, hbm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert_equals(size_t, 0, hbm_count(map)); - - cmc_assert(!hbm_update_key(map, 1, 1)); - - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hbm_flag(map)); - - hbm_free(map); - }); - - CMC_CREATE_TEST(update_key[not_found duplicate], { - struct hashbidimap *map = hbm_new(100, 0.7, hbm_fkey, hbm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert(hbm_insert(map, 1, 1)); - - cmc_assert_equals(size_t, 1, hbm_count(map)); - - map->flag = CMC_FLAG_ERROR; - cmc_assert(hbm_update_key(map, 1, 1)); - - cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map)); - - cmc_assert(!hbm_update_key(map, 2, 2)); - - cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hbm_flag(map)); - - cmc_assert(hbm_insert(map, 2, 2)); - - cmc_assert(!hbm_update_key(map, 1, 2)); - cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hbm_flag(map)); - cmc_assert(!hbm_update_key(map, 2, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hbm_flag(map)); - - cmc_assert(hbm_update_key(map, 2, 2)); - - hbm_free(map); - }); - - CMC_CREATE_TEST(update_val, { - struct hashbidimap *map = hbm_new(100, 0.7, hbm_fkey, hbm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 1; i <= 100; i++) - cmc_assert(hbm_insert(map, i, i)); - - cmc_assert_equals(size_t, 100, hbm_count(map)); - - for (size_t i = 100; i > 0; i--) - cmc_assert(hbm_update_val(map, i, i + 10)); - - cmc_assert_equals(size_t, 100, hbm_count(map)); - - for (size_t i = 1; i <= 100; i++) - cmc_assert_equals(size_t, i + 10, hbm_get_val(map, i)); - - cmc_assert_equals(size_t, 100, hbm_count(map)); - - hbm_free(map); - }); - - CMC_CREATE_TEST(update_val[empty], { - struct hashbidimap *map = hbm_new(100, 0.7, hbm_fkey, hbm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert_equals(size_t, 0, hbm_count(map)); - - cmc_assert(!hbm_update_val(map, 1, 1)); - - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hbm_flag(map)); - - hbm_free(map); - }); - - CMC_CREATE_TEST(update_val[not_found duplicate], { - struct hashbidimap *map = hbm_new(100, 0.7, hbm_fkey, hbm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert(hbm_insert(map, 1, 1)); - - cmc_assert_equals(size_t, 1, hbm_count(map)); - - map->flag = CMC_FLAG_ERROR; - cmc_assert(hbm_update_val(map, 1, 1)); - - cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map)); - - cmc_assert(!hbm_update_val(map, 2, 2)); - - cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hbm_flag(map)); - - cmc_assert(hbm_insert(map, 2, 2)); - - cmc_assert(!hbm_update_val(map, 1, 2)); - cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hbm_flag(map)); - cmc_assert(!hbm_update_val(map, 2, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hbm_flag(map)); - - cmc_assert(hbm_update_val(map, 2, 2)); - - hbm_free(map); - }); - - CMC_CREATE_TEST(remove_by_key[cleanup custom], { - struct hashbidimap *map = hbm_new_custom( - 10000, 0.6, hbm_fkey, hbm_fval, - &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free }, - &(struct cmc_callbacks){ 0 }); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 0; i < 10000; i++) - { - cmc_assert(hbm_insert(map, i, i)); - } - - for (size_t i = 0; i < 10000; i++) - { - cmc_assert(hbm_remove_by_key(map, i, NULL, NULL)); - } - - for (size_t i = 0; i < map->capacity; i++) - { - struct hashbidimap_entry *k = map->buffer[i][0]; - struct hashbidimap_entry *v = map->buffer[i][1]; - - cmc_assert((k == NULL || k == CMC_ENTRY_DELETED) && (v == NULL || v == CMC_ENTRY_DELETED)); - } - - hbm_free(map); - }); - - CMC_CREATE_TEST(remove_by_val[cleanup custom], { - struct hashbidimap *map = hbm_new_custom( - 10000, 0.6, hbm_fkey, hbm_fval, - &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free }, - &(struct cmc_callbacks){ 0 }); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 0; i < 10000; i++) - { - cmc_assert(hbm_insert(map, i, i)); - } - - for (size_t i = 0; i < 10000; i++) - { - cmc_assert(hbm_remove_by_val(map, i, NULL, NULL)); - } - - for (size_t i = 0; i < map->capacity; i++) - { - struct hashbidimap_entry *k = map->buffer[i][0]; - struct hashbidimap_entry *v = map->buffer[i][1]; - - cmc_assert((k == NULL || k == CMC_ENTRY_DELETED) && (v == NULL || v == CMC_ENTRY_DELETED)); - } - - hbm_free(map); - }); - - CMC_CREATE_TEST(copy_of, { - struct hashbidimap *map1 = hbm_new(100, 0.7, hbm_fkey, hbm_fval); - - for (size_t i = 0; i < 100; i++) - cmc_assert(hbm_insert(map1, i, i)); - - struct hashbidimap *map2 = hbm_copy_of(map1); - - cmc_assert_not_equals(ptr, NULL, map2); - cmc_assert_equals(size_t, hbm_count(map1), hbm_count(map2)); - - for (size_t i = 0; i < 100; i++) - { - cmc_assert(hbm_contains_key(map2, i) && hbm_contains_key(map1, i)); - cmc_assert(hbm_contains_val(map2, i) && hbm_contains_val(map1, i)); - } - - hbm_free(map1); - hbm_free(map2); - }); - - CMC_CREATE_TEST(equals, { - struct hashbidimap *map1 = hbm_new(100, 0.7, hbm_fkey, hbm_fval); - struct hashbidimap *map2 = hbm_new(1000, 0.9, hbm_fkey, hbm_fval); - - for (size_t i = 0; i < 100; i++) - { - cmc_assert(hbm_insert(map1, i, i)); - cmc_assert(hbm_insert(map2, 99 - i, 99 - i)); - } - - cmc_assert_not_equals(ptr, NULL, map1); - cmc_assert_not_equals(ptr, NULL, map2); - cmc_assert_equals(size_t, hbm_count(map1), hbm_count(map2)); - - for (size_t i = 0; i < 100; i++) - { - cmc_assert(hbm_contains_key(map2, i) && hbm_contains_key(map1, i)); - cmc_assert(hbm_contains_val(map2, i) && hbm_contains_val(map1, i)); - } - - hbm_free(map1); - hbm_free(map2); - }); - - CMC_CREATE_TEST(equals[from copy], { - struct hashbidimap *map1 = hbm_new(100, 0.7, hbm_fkey, hbm_fval); - - for (size_t i = 0; i < 100; i++) - cmc_assert(hbm_insert(map1, i, i)); - - struct hashbidimap *map2 = hbm_copy_of(map1); - - cmc_assert_not_equals(ptr, NULL, map2); - - cmc_assert(hbm_equals(map1, map2)); - - hbm_free(map1); - hbm_free(map2); - }); - - CMC_CREATE_TEST(flags, { - struct hashbidimap *map = hbm_new(100, 0.7, hbm_fkey, hbm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map)); - - // customize - hbm_customize(map, &cmc_alloc_node_default, &(struct cmc_callbacks){ 0 }); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map)); - - // Insert - cmc_assert(hbm_insert(map, 1, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map)); - - cmc_assert(!hbm_insert(map, 1, 2)); - cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hbm_flag(map)); - map->flag = CMC_FLAG_ERROR; - cmc_assert(!hbm_insert(map, 2, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hbm_flag(map)); - - // clear - hbm_clear(map); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map)); - - // hbm_update_key - cmc_assert(!hbm_update_key(map, 1, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hbm_flag(map)); - - cmc_assert(hbm_insert(map, 1, 1)); - cmc_assert(!hbm_update_key(map, 2, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hbm_flag(map)); - - cmc_assert(hbm_insert(map, 2, 2)); - cmc_assert(!hbm_update_key(map, 2, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hbm_flag(map)); - map->flag = CMC_FLAG_ERROR; - cmc_assert(!hbm_update_key(map, 1, 2)); - cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hbm_flag(map)); - - // clear - hbm_clear(map); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map)); - - // hbm_update_val - cmc_assert(!hbm_update_val(map, 1, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hbm_flag(map)); - - cmc_assert(hbm_insert(map, 1, 1)); - cmc_assert(!hbm_update_val(map, 2, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hbm_flag(map)); - - cmc_assert(hbm_insert(map, 2, 2)); - cmc_assert(!hbm_update_val(map, 2, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hbm_flag(map)); - map->flag = CMC_FLAG_ERROR; - cmc_assert(!hbm_update_val(map, 1, 2)); - cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hbm_flag(map)); - - // remove_by_key - cmc_assert(hbm_remove_by_key(map, 1, NULL, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map)); - - cmc_assert(!hbm_remove_by_key(map, 1, NULL, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hbm_flag(map)); - - cmc_assert(hbm_remove_by_key(map, 2, NULL, NULL)); - cmc_assert(!hbm_remove_by_key(map, 2, NULL, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hbm_flag(map)); - - // remove_by_val - cmc_assert(hbm_insert(map, 1, 1) && hbm_insert(map, 2, 2)); - - cmc_assert(hbm_remove_by_val(map, 1, NULL, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map)); - - cmc_assert(!hbm_remove_by_val(map, 1, NULL, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hbm_flag(map)); - - cmc_assert(hbm_remove_by_val(map, 2, NULL, NULL)); - cmc_assert(!hbm_remove_by_val(map, 2, NULL, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hbm_flag(map)); - - // get_key and get_val - cmc_assert(hbm_insert(map, 2, 1)); - - cmc_assert_equals(size_t, 2, hbm_get_key(map, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map)); - map->flag = CMC_FLAG_ERROR; - cmc_assert_equals(size_t, 1, hbm_get_val(map, 2)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map)); - - cmc_assert_equals(size_t, 0, hbm_get_key(map, 2)); - cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hbm_flag(map)); - map->flag = CMC_FLAG_ERROR; - cmc_assert_equals(size_t, 0, hbm_get_val(map, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hbm_flag(map)); - - // contains_key - cmc_assert(hbm_contains_key(map, 2)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map)); - - // contains_val - map->flag = CMC_FLAG_ERROR; - cmc_assert(hbm_contains_val(map, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map)); - - // copy_of - map->flag = CMC_FLAG_ERROR; - struct hashbidimap *map2 = hbm_copy_of(map); - - cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map2)); - - size_t tmp = map->capacity; - map->capacity = 0; - - struct hashbidimap *map3 = hbm_copy_of(map); - cmc_assert_equals(ptr, NULL, map3); - cmc_assert_equals(int32_t, CMC_FLAG_ERROR, hbm_flag(map)); - - map->capacity = tmp; - - // equals - hbm_get_key(map, 100); - hbm_get_key(map2, 100); - cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hbm_flag(map)); - cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hbm_flag(map2)); - map->flag = CMC_FLAG_ERROR; - cmc_assert(hbm_equals(map, map2)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map2)); - - hbm_free(map); - hbm_free(map2); - }); - - CMC_CREATE_TEST(callbacks, { - struct hashbidimap *map = hbm_new_custom(100, 0.7, hbm_fkey, hbm_fval, NULL, callbacks); - - cmc_assert_not_equals(ptr, NULL, map); - cmc_assert_equals(ptr, callbacks, map->callbacks); - - total_create = 0; - total_read = 0; - total_update = 0; - total_delete = 0; - total_resize = 0; - - cmc_assert(hbm_insert(map, 10, 10)); - cmc_assert_equals(int32_t, 1, total_create); - - cmc_assert(hbm_update_key(map, 10, 5)); - cmc_assert_equals(int32_t, 1, total_update); - - cmc_assert(hbm_update_val(map, 5, 5)); - cmc_assert_equals(int32_t, 2, total_update); - - cmc_assert(hbm_insert(map, 10, 10)); - cmc_assert_equals(int32_t, 2, total_create); - - cmc_assert(hbm_remove_by_key(map, 5, NULL, NULL)); - cmc_assert_equals(int32_t, 1, total_delete); - - cmc_assert(hbm_remove_by_val(map, 10, NULL, NULL)); - cmc_assert_equals(int32_t, 2, total_delete); - - cmc_assert(hbm_insert(map, 1, 2)); - cmc_assert_equals(int32_t, 3, total_create); - - cmc_assert_equals(size_t, 1, hbm_get_key(map, 2)); - cmc_assert_equals(int32_t, 1, total_read); - - cmc_assert_equals(size_t, 2, hbm_get_val(map, 1)); - cmc_assert_equals(int32_t, 2, total_read); - - cmc_assert(hbm_resize(map, 1000)); - cmc_assert_equals(int32_t, 1, total_resize); - - cmc_assert(hbm_resize(map, 200)); - cmc_assert_equals(int32_t, 2, total_resize); - - cmc_assert(hbm_contains_key(map, 1)); - cmc_assert_equals(int32_t, 3, total_read); - - cmc_assert(hbm_contains_val(map, 2)); - cmc_assert_equals(int32_t, 4, total_read); - - cmc_assert_equals(int32_t, 3, total_create); - cmc_assert_equals(int32_t, 4, total_read); - cmc_assert_equals(int32_t, 2, total_update); - cmc_assert_equals(int32_t, 2, total_delete); - cmc_assert_equals(int32_t, 2, total_resize); - - hbm_customize(map, NULL, NULL); - - cmc_assert_equals(ptr, NULL, map->callbacks); - - hbm_clear(map); - cmc_assert(hbm_insert(map, 10, 10)); - cmc_assert(hbm_update_key(map, 10, 5)); - cmc_assert(hbm_update_val(map, 5, 5)); - cmc_assert(hbm_insert(map, 10, 10)); - cmc_assert(hbm_remove_by_key(map, 5, NULL, NULL)); - cmc_assert(hbm_remove_by_val(map, 10, NULL, NULL)); - cmc_assert(hbm_insert(map, 1, 2)); - cmc_assert_equals(size_t, 1, hbm_get_key(map, 2)); - cmc_assert_equals(size_t, 2, hbm_get_val(map, 1)); - cmc_assert(hbm_resize(map, 1000)); - cmc_assert(hbm_resize(map, 200)); - cmc_assert(hbm_contains_key(map, 1)); - cmc_assert(hbm_contains_val(map, 2)); - - cmc_assert_equals(int32_t, 3, total_create); - cmc_assert_equals(int32_t, 4, total_read); - cmc_assert_equals(int32_t, 2, total_update); - cmc_assert_equals(int32_t, 2, total_delete); - cmc_assert_equals(int32_t, 2, total_resize); - - cmc_assert_equals(ptr, NULL, map->callbacks); - - hbm_free(map); - - total_create = 0; - total_read = 0; - total_update = 0; - total_delete = 0; - total_resize = 0; - }); -}); - -CMC_CREATE_UNIT(CMCHashBidiMapIter, true, { - CMC_CREATE_TEST(PFX##_iter_start, { - // WIP - cmc_assert(true); - cmc_assert(true); - }); -}); - -#ifdef CMC_TEST_MAIN -int main(void) -{ - int result = CMCHashBidiMap() + CMCHashBidiMapIter(); - - printf(" +---------------------------------------------------------------+"); - printf("\n"); - printf(" | CMCHashBidiMap Suit : %-42s |\n", result == 0 ? "PASSED" : "FAILED"); - printf(" +---------------------------------------------------------------+"); - printf("\n\n\n"); - - return result; -} -#endif - -#endif /* CMC_TESTS_UNT_CMC_ASHBIDIMAP_H */ diff --git a/tests/unt/unt_cmc_hashmap.h b/tests/unt/unt_cmc_hashmap.h deleted file mode 100644 index fee31f2..0000000 --- a/tests/unt/unt_cmc_hashmap.h +++ /dev/null @@ -1,1341 +0,0 @@ -#ifndef CMC_TESTS_UNT_CMC_ASHMAP_H -#define CMC_TESTS_UNT_CMC_ASHMAP_H - -#include "utl.h" - -#include "tst_cmc_hashmap.h" - -struct hashmap_fkey *hm_fkey = &(struct hashmap_fkey){ - .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp -}; - -struct hashmap_fval *hm_fval = &(struct hashmap_fval){ - .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp -}; - -struct hashmap_fkey *hm_fkey_counter = &(struct hashmap_fkey){ - .cmp = k_c_cmp, .cpy = k_c_cpy, .str = k_c_str, .free = k_c_free, .hash = k_c_hash, .pri = k_c_pri -}; - -struct hashmap_fval *hm_fval_counter = &(struct hashmap_fval){ - .cmp = v_c_cmp, .cpy = v_c_cpy, .str = v_c_str, .free = v_c_free, .hash = v_c_hash, .pri = v_c_pri -}; - -struct cmc_alloc_node *hm_alloc_node = - &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free }; - -CMC_CREATE_UNIT(CMCHashMap, true, { - CMC_CREATE_TEST(PFX##_new(), { - struct hashmap *map = hm_new(943722, 0.6, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - cmc_assert_not_equals(ptr, NULL, map->buffer); - cmc_assert_equals(size_t, 0, map->count); - cmc_assert_equals(double, 0.6, map->load); - cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag); - cmc_assert_equals(ptr, hm_fkey, map->f_key); - cmc_assert_equals(ptr, hm_fval, map->f_val); - cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, map->alloc->malloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, map->alloc->calloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, map->alloc->realloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.free, map->alloc->free); - cmc_assert_equals(ptr, NULL, map->callbacks); - - cmc_assert_greater_equals(size_t, (943722 / 0.6), hm_capacity(map)); - - hm_free(map); - - map = hm_new(0, 0.6, hm_fkey, hm_fval); - cmc_assert_equals(ptr, NULL, map); - - map = hm_new(UINT64_MAX, 0.99, hm_fkey, hm_fval); - cmc_assert_equals(ptr, NULL, map); - - map = hm_new(1000, 0.6, hm_fkey, NULL); - cmc_assert_equals(ptr, NULL, map); - - map = hm_new(1000, 0.6, NULL, hm_fval); - cmc_assert_equals(ptr, NULL, map); - - map = hm_new(1000, 0.6, NULL, NULL); - cmc_assert_equals(ptr, NULL, map); - }); - - CMC_CREATE_TEST(PFX##_new_custom(), { - struct hashmap *map = hm_new_custom(943722, 0.6, hm_fkey, hm_fval, hm_alloc_node, callbacks); - - cmc_assert_not_equals(ptr, NULL, map); - cmc_assert_not_equals(ptr, NULL, map->buffer); - cmc_assert_equals(size_t, 0, map->count); - cmc_assert_equals(double, 0.6, map->load); - cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag); - cmc_assert_equals(ptr, hm_fkey, map->f_key); - cmc_assert_equals(ptr, hm_fval, map->f_val); - cmc_assert_equals(ptr, hm_alloc_node, map->alloc); - cmc_assert_equals(ptr, callbacks, map->callbacks); - - cmc_assert_greater_equals(size_t, (943722 / 0.6), hm_capacity(map)); - - hm_free(map); - - map = hm_new_custom(0, 0.6, hm_fkey, hm_fval, NULL, NULL); - cmc_assert_equals(ptr, NULL, map); - - map = hm_new_custom(UINT64_MAX, 0.99, hm_fkey, hm_fval, NULL, NULL); - cmc_assert_equals(ptr, NULL, map); - - map = hm_new_custom(1000, 0.6, hm_fkey, NULL, NULL, NULL); - cmc_assert_equals(ptr, NULL, map); - - map = hm_new_custom(1000, 0.6, NULL, hm_fval, NULL, NULL); - cmc_assert_equals(ptr, NULL, map); - - map = hm_new_custom(1000, 0.6, NULL, NULL, NULL, NULL); - cmc_assert_equals(ptr, NULL, map); - }); - - CMC_CREATE_TEST(PFX##_init(), { - struct hashmap map = hm_init(943722, 0.6, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map.buffer); - cmc_assert_equals(size_t, 0, map.count); - cmc_assert_equals(double, 0.6, map.load); - cmc_assert_equals(int32_t, CMC_FLAG_OK, map.flag); - cmc_assert_equals(ptr, hm_fkey, map.f_key); - cmc_assert_equals(ptr, hm_fval, map.f_val); - cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, map.alloc->malloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, map.alloc->calloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, map.alloc->realloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.free, map.alloc->free); - cmc_assert_equals(ptr, NULL, map.callbacks); - - cmc_assert_greater_equals(size_t, (943722 / 0.6), hm_capacity(&map)); - - hm_release(map); - - map = hm_init(0, 0.6, hm_fkey, hm_fval); - cmc_assert_equals(ptr, NULL, map.buffer); - - map = hm_init(UINT64_MAX, 0.99, hm_fkey, hm_fval); - cmc_assert_equals(ptr, NULL, map.buffer); - - map = hm_init(1000, 0.6, hm_fkey, NULL); - cmc_assert_equals(ptr, NULL, map.buffer); - - map = hm_init(1000, 0.6, NULL, hm_fval); - cmc_assert_equals(ptr, NULL, map.buffer); - - map = hm_init(1000, 0.6, NULL, NULL); - cmc_assert_equals(ptr, NULL, map.buffer); - }); - - CMC_CREATE_TEST(PFX##_init_custom(), { - struct hashmap map = hm_init_custom(943722, 0.6, hm_fkey, hm_fval, hm_alloc_node, callbacks); - - cmc_assert_not_equals(ptr, NULL, map.buffer); - cmc_assert_equals(size_t, 0, map.count); - cmc_assert_equals(double, 0.6, map.load); - cmc_assert_equals(int32_t, CMC_FLAG_OK, map.flag); - cmc_assert_equals(ptr, hm_fkey, map.f_key); - cmc_assert_equals(ptr, hm_fval, map.f_val); - cmc_assert_equals(ptr, hm_alloc_node, map.alloc); - cmc_assert_equals(ptr, callbacks, map.callbacks); - - cmc_assert_greater_equals(size_t, (943722 / 0.6), hm_capacity(&map)); - - hm_release(map); - - map = hm_init_custom(0, 0.6, hm_fkey, hm_fval, NULL, NULL); - cmc_assert_equals(ptr, NULL, map.buffer); - - map = hm_init_custom(UINT64_MAX, 0.99, hm_fkey, hm_fval, NULL, NULL); - cmc_assert_equals(ptr, NULL, map.buffer); - - map = hm_init_custom(1000, 0.6, hm_fkey, NULL, NULL, NULL); - cmc_assert_equals(ptr, NULL, map.buffer); - - map = hm_init_custom(1000, 0.6, NULL, hm_fval, NULL, NULL); - cmc_assert_equals(ptr, NULL, map.buffer); - - map = hm_init_custom(1000, 0.6, NULL, NULL, NULL, NULL); - cmc_assert_equals(ptr, NULL, map.buffer); - }); - - CMC_CREATE_TEST(PFX##_clear(), { - k_total_free = 0; - v_total_free = 0; - struct hashmap *map = hm_new(100, 0.6, hm_fkey_counter, hm_fval_counter); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 1; i <= 1000; i++) - hm_insert(map, i, i); - - cmc_assert_equals(size_t, 1000, map->count); - - size_t *r = hm_get_ref(map, 100); - - cmc_assert_equals(size_t, 100, *r); - - map->flag = CMC_FLAG_ERROR; - hm_clear(map); - - cmc_assert_equals(size_t, 0, map->count); - cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag); - cmc_assert_equals(int32_t, 1000, k_total_free); - cmc_assert_equals(int32_t, 1000, v_total_free); - - // The buffer is still valid and all zeroes - cmc_assert_equals(size_t, 0, *r); - - hm_free(map); - k_total_free = 0; - v_total_free = 0; - }); - - CMC_CREATE_TEST(PFX##_free(), { - k_total_free = 0; - v_total_free = 0; - struct hashmap *map = hm_new(100, 0.6, hm_fkey_counter, hm_fval_counter); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 1; i <= 1000; i++) - hm_insert(map, i, i); - - cmc_assert_equals(size_t, 1000, map->count); - - hm_free(map); - - cmc_assert_equals(int32_t, 1000, k_total_free); - cmc_assert_equals(int32_t, 1000, v_total_free); - - map = hm_new(1000, 0.6, hm_fkey_counter, hm_fval_counter); - - cmc_assert_not_equals(ptr, NULL, map); - cmc_assert_not_equals(ptr, NULL, map->buffer); - - hm_free(map); - - cmc_assert_equals(int32_t, 1000, k_total_free); - cmc_assert_equals(int32_t, 1000, v_total_free); - k_total_free = 0; - v_total_free = 0; - }); - - CMC_CREATE_TEST(PFX##_release(), { - k_total_free = 0; - v_total_free = 0; - struct hashmap map = hm_init(100, 0.6, hm_fkey_counter, hm_fval_counter); - - cmc_assert_not_equals(ptr, NULL, map.buffer); - - for (size_t i = 1; i <= 1000; i++) - hm_insert(&map, i, i); - - cmc_assert_equals(size_t, 1000, map.count); - - hm_release(map); - - cmc_assert_equals(int32_t, 1000, k_total_free); - cmc_assert_equals(int32_t, 1000, v_total_free); - - map = hm_init(1000, 0.6, hm_fkey_counter, hm_fval_counter); - - cmc_assert_not_equals(ptr, NULL, map.buffer); - - hm_release(map); - - cmc_assert_equals(int32_t, 1000, k_total_free); - cmc_assert_equals(int32_t, 1000, v_total_free); - k_total_free = 0; - v_total_free = 0; - }); - - CMC_CREATE_TEST(PFX##_customize(), { - struct hashmap *map = hm_new(100, 0.6, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - map->flag = CMC_FLAG_ERROR; - hm_customize(map, hm_alloc_node, callbacks); - - cmc_assert_equals(ptr, hm_alloc_node, map->alloc); - cmc_assert_equals(ptr, callbacks, map->callbacks); - cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag); - - map->flag = CMC_FLAG_ERROR; - hm_customize(map, NULL, NULL); - - cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, map->alloc->malloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, map->alloc->calloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, map->alloc->realloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.free, map->alloc->free); - cmc_assert_equals(ptr, NULL, map->callbacks); - cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag); - - hm_free(map); - }); - - CMC_CREATE_TEST(PFX##_insert(), { - struct hashmap *map = hm_new(100, 0.6, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - map->flag = CMC_FLAG_ERROR; - cmc_assert(hm_insert(map, 1, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag); - cmc_assert_equals(size_t, 1, hm_count(map)); - - hm_free(map); - - map = hm_new(1, 0.99, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert_equals(size_t, cmc_hashtable_primes[0], hm_capacity(map)); - cmc_assert(hm_insert(map, 1, 1)); - - hm_free(map); - - // element position - map = hm_new(1, 0.99, hm_fkey, hm_fval); - - // Temporary change - // Using the numhash the key is the hash itself - hm_fkey->hash = numhash; - - cmc_assert_not_equals(ptr, NULL, map); - - size_t capacity = hm_capacity(map); - - cmc_assert_greater(size_t, 0, capacity); - - cmc_assert(hm_insert(map, capacity - 1, capacity - 1)); - cmc_assert(hm_insert(map, capacity, capacity)); - - cmc_assert_equals(size_t, capacity - 1, map->buffer[capacity - 1].key); - cmc_assert_equals(size_t, capacity, map->buffer[0].key); - - hm_fkey->hash = cmc_size_hash; - - hm_free(map); - - // distance - map = hm_new(500, 0.6, hm_fkey, hm_fval); - - // Temporary change - hm_fkey->hash = hash0; - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 0; i < 200; i++) - cmc_assert(hm_insert(map, i, i)); - - // Everything is hashed to 0 so key 0 should have dist 0, key 1 dist 1, - // etc - for (size_t i = 0; i < 200; i++) - cmc_assert_equals(size_t, i, map->buffer[i].dist); - - hm_fkey->hash = cmc_size_hash; - - hm_free(map); - - // distance wrap - map = hm_new(1, 0.99, hm_fkey, hm_fval); - - // Temporary change - hm_fkey->hash = hashcapminus1; - - cmc_assert_not_equals(ptr, NULL, map); - - capacity = hm_capacity(map); - - // Just to be sure, not part of the test - cmc_assert_equals(size_t, cmc_hashtable_primes[0] - 1, hashcapminus1(0)); - cmc_assert_equals(size_t, capacity - 1, hashcapminus1(0)); - - cmc_assert(hm_insert(map, 0, 0)); - cmc_assert(hm_insert(map, 1, 1)); - - cmc_assert_equals(size_t, 0, map->buffer[capacity - 1].dist); - cmc_assert_equals(size_t, 1, map->buffer[0].dist); - - hm_fkey->hash = cmc_size_hash; - - hm_free(map); - - // distances - map = hm_new(1, 0.99, hm_fkey, hm_fval); - - // Temporary change - hm_fkey->hash = hashcapminus4; - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert_equals(size_t, cmc_hashtable_primes[0], hm_capacity(map)); - - for (size_t i = 0; i < 6; i++) - cmc_assert(hm_insert(map, i, i)); - - // for (size_t i = 0; i < 6; i++) - // cmc_assert_equals(size_t, i, hm_impl_get_entry(map, i)->dist); - - hm_fkey->hash = cmc_size_hash; - - hm_free(map); - - // buffer growth and item preservation - map = hm_new(1, 0.99, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert_equals(size_t, cmc_hashtable_primes[0], hm_capacity(map)); - - size_t p = 0; - for (size_t i = 0; i < 100000; i++) - { - if (hm_full(map)) - p++; - - cmc_assert(hm_insert(map, i, i)); - } - - cmc_assert_equals(size_t, cmc_hashtable_primes[p], hm_capacity(map)); - - for (size_t i = 0; i < 100000; i++) - cmc_assert(hm_contains(map, i)); - - hm_free(map); - }); - - CMC_CREATE_TEST(PFX##_update(), { - struct hashmap *map = hm_new(100, 0.6, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert(hm_insert(map, 1, 1)); - - size_t old; - cmc_assert(hm_update(map, 1, 2, &old)); - - cmc_assert_equals(size_t, 1, old); - - hm_free(map); - - // key not found - map = hm_new(100, 0.6, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 0; i < 100; i++) - hm_insert(map, i, i); - - cmc_assert(!hm_update(map, 120, 120, NULL)); - - hm_free(map); - }); - - CMC_CREATE_TEST(PFX##_remove(), { - struct hashmap *map = hm_new(100, 0.6, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 0; i < 100; i++) - hm_insert(map, i, i); - - for (size_t i = 0; i < 100; i++) - cmc_assert(hm_remove(map, i, NULL)); - - hm_free(map); - - // count = 0 - map = hm_new(100, 0.6, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 100; i < 200; i++) - cmc_assert(!hm_remove(map, i, NULL)); - - hm_free(map); - - // key not found - map = hm_new(100, 0.6, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 0; i < 100; i++) - hm_insert(map, i, i); - - cmc_assert_equals(size_t, 100, map->count); - - for (size_t i = 100; i < 200; i++) - cmc_assert(!hm_remove(map, i, NULL)); - - hm_free(map); - }); - - CMC_CREATE_TEST(PFX##_max(), { - struct hashmap *map = hm_new(100, 0.6, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 1; i <= 100; i++) - cmc_assert(hm_insert(map, i, i)); - - size_t key; - size_t val; - cmc_assert(hm_max(map, &key, &val)); - - cmc_assert_equals(size_t, 100, key); - cmc_assert_equals(size_t, 100, val); - - hm_free(map); - - // count = 0 - map = hm_new(100, 0.6, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert(!hm_min(map, NULL, NULL)); - - hm_free(map); - }); - - CMC_CREATE_TEST(PFX##_min(), { - struct hashmap *map = hm_new(100, 0.6, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 1; i <= 100; i++) - cmc_assert(hm_insert(map, i, i)); - - size_t key; - size_t val; - cmc_assert(hm_min(map, &key, &val)); - - cmc_assert_equals(size_t, 1, key); - cmc_assert_equals(size_t, 1, val); - - hm_free(map); - - // count = 0 - map = hm_new(100, 0.6, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert(!hm_min(map, NULL, NULL)); - - hm_free(map); - }); - - CMC_CREATE_TEST(PFX##_get(), { - struct hashmap *map = hm_new(100, 0.6, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert(hm_insert(map, 4321, 1234)); - - cmc_assert_equals(size_t, 1234, hm_get(map, 4321)); - - hm_free(map); - - // count = 0 - map = hm_new(100, 0.6, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert_equals(size_t, (size_t){ 0 }, hm_get(map, 4321)); - - hm_free(map); - }); - - CMC_CREATE_TEST(PFX##_get_ref(), { - struct hashmap *map = hm_new(100, 0.6, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert(hm_insert(map, 4321, 1234)); - - size_t *result = hm_get_ref(map, 4321); - - cmc_assert_not_equals(ptr, NULL, result); - cmc_assert_equals(size_t, 1234, *result); - - hm_free(map); - - // count = 0 - map = hm_new(100, 0.6, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert_equals(ptr, NULL, hm_get_ref(map, 4321)); - - hm_free(map); - }); - - CMC_CREATE_TEST(PFX##_contains(), { - struct hashmap *map = hm_new(100, 0.6, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert(hm_insert(map, 987654321, 1)); - - cmc_assert(hm_contains(map, 987654321)); - - hm_free(map); - - // count = 0 - map = hm_new(100, 0.6, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert(!hm_contains(map, 987654321)); - - hm_free(map); - - // sum - map = hm_new(100, 0.6, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 101; i <= 200; i++) - cmc_assert(hm_insert(map, i, i)); - - size_t sum = 0; - for (size_t i = 1; i <= 300; i++) - if (hm_contains(map, i)) - sum += i; - - cmc_assert_equals(size_t, 15050, sum); - - hm_free(map); - }); - - CMC_CREATE_TEST(PFX##_empty(), { - struct hashmap *map = hm_new(100, 0.6, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert(hm_empty(map)); - - cmc_assert(hm_insert(map, 1, 1)); - - cmc_assert(!hm_empty(map)); - - hm_free(map); - }); - - CMC_CREATE_TEST(PFX##_full(), { - struct hashmap *map = hm_new(cmc_hashtable_primes[0], 0.99999, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert_equals(size_t, cmc_hashtable_primes[0], hm_capacity(map)); - - for (size_t i = 0; i < hm_capacity(map); i++) - cmc_assert(hm_insert(map, i, i)); - - cmc_assert(hm_full(map)); - - cmc_assert(hm_insert(map, 10000, 10000)); - - cmc_assert_equals(size_t, cmc_hashtable_primes[1], hm_capacity(map)); - - cmc_assert(!hm_full(map)); - - hm_free(map); - }); - - CMC_CREATE_TEST(PFX##_count(), { - struct hashmap *map = hm_new(100, 0.6, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 1; i < 100; i++) - { - cmc_assert(hm_insert(map, i, i)); - cmc_assert_equals(size_t, i, hm_count(map)); - } - - hm_free(map); - }); - - CMC_CREATE_TEST(PFX##_capacity(), { - struct hashmap *map = hm_new(2500, 0.6, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert_greater_equals(size_t, (size_t)(2500 / 0.6), hm_capacity(map)); - - hm_free(map); - - // small capacity - map = hm_new(1, 0.99, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert_equals(size_t, cmc_hashtable_primes[0], hm_capacity(map)); - - hm_free(map); - }); - - CMC_CREATE_TEST(PFX##_load(), { - struct hashmap *map = hm_new(1, 0.99, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert_in_range(double, 0.99 - 0.0001, 0.99 + 0.0001, hm_load(map)); - - hm_free(map); - }); - - CMC_CREATE_TEST(flags, { - struct hashmap *map = hm_new(100, 0.6, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map)); - - // insert - cmc_assert(hm_insert(map, 1, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map)); - cmc_assert(!hm_insert(map, 1, 2)); - cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hm_flag(map)); - - // clear - hm_clear(map); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map)); - - // update - cmc_assert(!hm_update(map, 1, 2, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hm_flag(map)); - - cmc_assert(hm_insert(map, 1, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map)); - - cmc_assert(!hm_update(map, 2, 1, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hm_flag(map)); - - cmc_assert(hm_update(map, 1, 2, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map)); - - // remove - cmc_assert(!hm_remove(map, 2, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hm_flag(map)); - - cmc_assert(hm_remove(map, 1, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map)); - - cmc_assert(!hm_remove(map, 1, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hm_flag(map)); - - // max - cmc_assert(hm_insert(map, 1, 1)); - cmc_assert(hm_max(map, NULL, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map)); - - cmc_assert(hm_remove(map, 1, NULL)); - cmc_assert(!hm_max(map, NULL, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hm_flag(map)); - - // min - cmc_assert(hm_insert(map, 1, 1)); - cmc_assert(hm_min(map, NULL, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map)); - - cmc_assert(hm_remove(map, 1, NULL)); - cmc_assert(!hm_min(map, NULL, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hm_flag(map)); - - // get - hm_get(map, 1); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hm_flag(map)); - - cmc_assert(hm_insert(map, 1, 1)); - hm_get(map, 1); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map)); - - hm_get(map, 2); - cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hm_flag(map)); - - hm_clear(map); - - // get_ref - hm_get_ref(map, 1); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hm_flag(map)); - - cmc_assert(hm_insert(map, 1, 1)); - hm_get_ref(map, 1); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map)); - - hm_get_ref(map, 2); - cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hm_flag(map)); - - // contains - hm_contains(map, 1); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map)); - - // copy - struct hashmap *map2 = hm_copy_of(map); - - cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map2)); - - size_t tmp = map->capacity; - map->capacity = 0; - - struct hashmap *map3 = hm_copy_of(map); - cmc_assert_equals(ptr, NULL, map3); - - cmc_assert_equals(int32_t, CMC_FLAG_ERROR, hm_flag(map)); - - map->capacity = tmp; - - cmc_assert(hm_equals(map, map2)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map2)); - - hm_free(map); - hm_free(map2); - }); - - CMC_CREATE_TEST(callbacks, { - struct hashmap *map = hm_new_custom(100, 0.6, hm_fkey, hm_fval, NULL, callbacks); - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert(hm_insert(map, 1, 2)); - cmc_assert_equals(int32_t, 1, total_create); - - cmc_assert(hm_update(map, 1, 10, NULL)); - cmc_assert_equals(int32_t, 1, total_update); - - cmc_assert(hm_remove(map, 1, NULL)); - cmc_assert_equals(int32_t, 1, total_delete); - - cmc_assert(hm_insert(map, 1, 2)); - cmc_assert_equals(int32_t, 2, total_create); - - cmc_assert(hm_max(map, NULL, NULL)); - cmc_assert_equals(int32_t, 1, total_read); - - cmc_assert(hm_min(map, NULL, NULL)); - cmc_assert_equals(int32_t, 2, total_read); - - cmc_assert_equals(size_t, 2, hm_get(map, 1)); - cmc_assert_equals(int32_t, 3, total_read); - - cmc_assert_not_equals(ptr, NULL, hm_get_ref(map, 1)); - cmc_assert_equals(int32_t, 4, total_read); - - cmc_assert(hm_contains(map, 1)); - cmc_assert_equals(int32_t, 5, total_read); - - cmc_assert(hm_resize(map, 10000)); - cmc_assert_equals(int32_t, 1, total_resize); - - cmc_assert(hm_resize(map, 500)); - cmc_assert_equals(int32_t, 2, total_resize); - - cmc_assert_equals(int32_t, 2, total_create); - cmc_assert_equals(int32_t, 5, total_read); - cmc_assert_equals(int32_t, 1, total_update); - cmc_assert_equals(int32_t, 1, total_delete); - cmc_assert_equals(int32_t, 2, total_resize); - - hm_customize(map, NULL, NULL); - - cmc_assert_equals(ptr, NULL, map->callbacks); - - hm_clear(map); - cmc_assert(hm_insert(map, 1, 2)); - cmc_assert(hm_update(map, 1, 10, NULL)); - cmc_assert(hm_remove(map, 1, NULL)); - cmc_assert(hm_insert(map, 1, 2)); - cmc_assert(hm_max(map, NULL, NULL)); - cmc_assert(hm_min(map, NULL, NULL)); - cmc_assert_equals(size_t, 2, hm_get(map, 1)); - cmc_assert_not_equals(ptr, NULL, hm_get_ref(map, 1)); - cmc_assert(hm_contains(map, 1)); - cmc_assert(hm_resize(map, 10000)); - cmc_assert(hm_resize(map, 500)); - - cmc_assert_equals(int32_t, 2, total_create); - cmc_assert_equals(int32_t, 5, total_read); - cmc_assert_equals(int32_t, 1, total_update); - cmc_assert_equals(int32_t, 1, total_delete); - cmc_assert_equals(int32_t, 2, total_resize); - - cmc_assert_equals(ptr, NULL, map->callbacks); - - hm_free(map); - - total_create = 0; - total_read = 0; - total_update = 0; - total_delete = 0; - total_resize = 0; - }); -}); - -struct hashmap_fkey *hm_fkey_numhash = &(struct hashmap_fkey){ - .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = numhash, .pri = cmc_size_cmp -}; - -CMC_CREATE_UNIT(CMCHashMapIter, true, { - CMC_CREATE_TEST(PFX##_iter_start(), { - struct hashmap *map = hm_new(100, 0.6, hm_fkey_numhash, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct hashmap_iter it = hm_iter_start(map); - - cmc_assert_equals(ptr, map, it.target); - cmc_assert_equals(size_t, 0, it.cursor); - cmc_assert_equals(size_t, 0, it.index); - cmc_assert_equals(size_t, 0, it.first); - cmc_assert_equals(size_t, 0, it.last); - cmc_assert_equals(bool, true, it.start); - cmc_assert_equals(bool, true, it.end); - - cmc_assert(hm_iter_at_start(&it)); - cmc_assert(hm_iter_at_end(&it)); - - cmc_assert(hm_insert(map, 1, 1)); - cmc_assert(hm_insert(map, 2, 2)); - cmc_assert(hm_insert(map, 3, 3)); - - it = hm_iter_start(map); - - cmc_assert_equals(size_t, 0, it.index); - - cmc_assert_equals(size_t, 1, it.cursor); - cmc_assert_equals(size_t, 1, it.first); - cmc_assert_equals(size_t, 3, it.last); - cmc_assert_equals(bool, false, it.end); - - hm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_end(), { - struct hashmap *map = hm_new(100, 0.6, hm_fkey_numhash, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct hashmap_iter it = hm_iter_end(map); - - cmc_assert_equals(ptr, map, it.target); - cmc_assert_equals(size_t, 0, it.cursor); - cmc_assert_equals(size_t, 0, it.index); - cmc_assert_equals(size_t, 0, it.first); - cmc_assert_equals(size_t, 0, it.last); - cmc_assert_equals(bool, true, it.start); - cmc_assert_equals(bool, true, it.end); - - cmc_assert(hm_iter_at_start(&it)); - cmc_assert(hm_iter_at_end(&it)); - - cmc_assert(hm_insert(map, 1, 1)); - cmc_assert(hm_insert(map, 2, 2)); - cmc_assert(hm_insert(map, 3, 3)); - - it = hm_iter_end(map); - - cmc_assert_equals(size_t, map->count - 1, it.index); - - cmc_assert_equals(size_t, 3, it.cursor); - cmc_assert_equals(size_t, 1, it.first); - cmc_assert_equals(size_t, 3, it.last); - cmc_assert_equals(bool, false, it.start); - - hm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_at_start(), { - struct hashmap *map = hm_new(100, 0.6, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct hashmap_iter it = hm_iter_start(map); - - // Empty checks - cmc_assert(hm_iter_at_start(&it)); - it = hm_iter_end(map); - cmc_assert(hm_iter_at_start(&it)); - - // Non-empty checks - cmc_assert(hm_insert(map, 1, 1)); - cmc_assert(hm_insert(map, 2, 2)); - it = hm_iter_end(map); - cmc_assert(!hm_iter_at_start(&it)); - it = hm_iter_start(map); - cmc_assert(hm_iter_at_start(&it)); - - hm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_at_end(), { - struct hashmap *map = hm_new(100, 0.6, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct hashmap_iter it = hm_iter_start(map); - - // Empty check - cmc_assert(hm_iter_at_end(&it)); - it = hm_iter_end(map); - cmc_assert(hm_iter_at_end(&it)); - - // Non-empty checks - cmc_assert(hm_insert(map, 1, 1)); - cmc_assert(hm_insert(map, 2, 2)); - it = hm_iter_end(map); - cmc_assert(hm_iter_at_end(&it)); - it = hm_iter_start(map); - cmc_assert(!hm_iter_at_end(&it)); - - hm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_to_start(), { - struct hashmap *map = hm_new(100, 0.6, hm_fkey_numhash, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct hashmap_iter it = hm_iter_start(map); - - cmc_assert(!hm_iter_to_start(&it)); - - for (size_t i = 1; i <= 100; i++) - hm_insert(map, i, i); - - cmc_assert_equals(size_t, 100, map->count); - - it = hm_iter_end(map); - - cmc_assert(!hm_iter_at_start(&it)); - cmc_assert(hm_iter_at_end(&it)); - - cmc_assert_equals(size_t, 100, hm_iter_value(&it)); - - cmc_assert(hm_iter_to_start(&it)); - - cmc_assert(hm_iter_at_start(&it)); - cmc_assert(!hm_iter_at_end(&it)); - - cmc_assert_equals(size_t, 1, hm_iter_value(&it)); - - hm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_to_end(), { - struct hashmap *map = hm_new(100, 0.6, hm_fkey_numhash, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct hashmap_iter it = hm_iter_end(map); - - cmc_assert(!hm_iter_to_end(&it)); - - for (size_t i = 1; i <= 100; i++) - hm_insert(map, i, i); - - it = hm_iter_start(map); - - cmc_assert(hm_iter_at_start(&it)); - cmc_assert(!hm_iter_at_end(&it)); - - cmc_assert_equals(size_t, 1, hm_iter_value(&it)); - - cmc_assert(hm_iter_to_end(&it)); - - cmc_assert(!hm_iter_at_start(&it)); - cmc_assert(hm_iter_at_end(&it)); - - cmc_assert_equals(size_t, 100, hm_iter_value(&it)); - - hm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_next(), { - struct hashmap *map = hm_new(100, 0.6, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct hashmap_iter it = hm_iter_start(map); - - cmc_assert(!hm_iter_next(&it)); - - for (size_t i = 1; i <= 1000; i++) - hm_insert(map, i, i); - - size_t sum = 0; - for (it = hm_iter_start(map); !hm_iter_at_end(&it); hm_iter_next(&it)) - { - sum += hm_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - - hm_iter_to_start(&it); - do - { - sum += hm_iter_value(&it); - } while (hm_iter_next(&it)); - - cmc_assert_equals(size_t, 500500, sum); - - hm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_prev(), { - struct hashmap *map = hm_new(100, 0.6, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct hashmap_iter it = hm_iter_end(map); - - cmc_assert(!hm_iter_prev(&it)); - - for (size_t i = 1; i <= 1000; i++) - hm_insert(map, i, i); - - size_t sum = 0; - for (it = hm_iter_end(map); !hm_iter_at_start(&it); hm_iter_prev(&it)) - { - sum += hm_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - - hm_iter_to_end(&it); - do - { - sum += hm_iter_value(&it); - } while (hm_iter_prev(&it)); - - cmc_assert_equals(size_t, 500500, sum); - - hm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_advance(), { - struct hashmap *map = hm_new(100, 0.6, hm_fkey_numhash, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct hashmap_iter it = hm_iter_start(map); - - cmc_assert(!hm_iter_advance(&it, 1)); - - for (size_t i = 0; i <= 1000; i++) - hm_insert(map, i, i); - - it = hm_iter_start(map); - - cmc_assert(!hm_iter_advance(&it, 0)); - cmc_assert(!hm_iter_advance(&it, map->count)); - - size_t sum = 0; - for (it = hm_iter_start(map);;) - { - sum += hm_iter_value(&it); - - if (!hm_iter_advance(&it, 2)) - break; - } - - cmc_assert_equals(size_t, 250500, sum); - - hm_iter_to_start(&it); - cmc_assert(hm_iter_advance(&it, map->count - 1)); - - hm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_rewind(), { - struct hashmap *map = hm_new(100, 0.6, hm_fkey_numhash, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct hashmap_iter it = hm_iter_end(map); - - cmc_assert(!hm_iter_rewind(&it, 1)); - - for (size_t i = 0; i <= 1000; i++) - hm_insert(map, i, i); - - it = hm_iter_end(map); - - cmc_assert(!hm_iter_rewind(&it, 0)); - cmc_assert(!hm_iter_rewind(&it, map->count)); - - size_t sum = 0; - for (it = hm_iter_end(map);;) - { - sum += hm_iter_value(&it); - - if (!hm_iter_rewind(&it, 2)) - break; - } - - cmc_assert_equals(size_t, 250500, sum); - - hm_iter_to_end(&it); - cmc_assert(hm_iter_rewind(&it, map->count - 1)); - - hm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_go_to(), { - struct hashmap *map = hm_new(100, 0.6, hm_fkey_numhash, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct hashmap_iter it = hm_iter_end(map); - cmc_assert(!hm_iter_go_to(&it, 0)); - - it = hm_iter_start(map); - cmc_assert(!hm_iter_go_to(&it, 0)); - - for (size_t i = 0; i <= 1000; i++) - hm_insert(map, i, i); - - it = hm_iter_start(map); - - size_t sum = 0; - for (size_t i = 0; i < 1001; i++) - { - hm_iter_go_to(&it, i); - - sum += hm_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - for (size_t i = 1001; i > 0; i--) - { - cmc_assert(hm_iter_go_to(&it, i - 1)); - - sum += hm_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - for (size_t i = 0; i < 1001; i += 100) - { - cmc_assert(hm_iter_go_to(&it, i)); - cmc_assert_equals(size_t, i, hm_iter_index(&it)); - - sum += hm_iter_value(&it); - } - - cmc_assert_equals(size_t, 5500, sum); - - hm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_key(), { - struct hashmap *map = hm_new(100, 0.6, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct hashmap_iter it = hm_iter_end(map); - - cmc_assert_equals(size_t, (size_t){ 0 }, hm_iter_key(&it)); - - cmc_assert(hm_insert(map, 10, 10)); - - it = hm_iter_start(map); - - cmc_assert_equals(size_t, 10, hm_iter_key(&it)); - - hm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_value(), { - struct hashmap *map = hm_new(100, 0.6, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct hashmap_iter it = hm_iter_end(map); - - cmc_assert_equals(size_t, (size_t){ 0 }, hm_iter_value(&it)); - - cmc_assert(hm_insert(map, 10, 10)); - - it = hm_iter_start(map); - - cmc_assert_equals(size_t, 10, hm_iter_value(&it)); - - hm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_rvalue(), { - struct hashmap *map = hm_new(100, 0.6, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct hashmap_iter it = hm_iter_end(map); - - cmc_assert_equals(ptr, NULL, hm_iter_rvalue(&it)); - - cmc_assert(hm_insert(map, 10, 10)); - - it = hm_iter_start(map); - - cmc_assert_not_equals(ptr, NULL, hm_iter_rvalue(&it)); - cmc_assert_equals(size_t, 10, *hm_iter_rvalue(&it)); - - hm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_index(), { - struct hashmap *map = hm_new(100, 0.6, hm_fkey, hm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 0; i <= 1000; i++) - hm_insert(map, i, i); - - struct hashmap_iter it = hm_iter_start(map); - - for (size_t i = 0; i < 1001; i++) - { - cmc_assert_equals(size_t, i, hm_iter_index(&it)); - hm_iter_next(&it); - } - - it = hm_iter_end(map); - for (size_t i = 1001; i > 0; i--) - { - cmc_assert_equals(size_t, i - 1, hm_iter_index(&it)); - hm_iter_prev(&it); - } - - hm_free(map); - }); -}); - -#ifdef CMC_TEST_MAIN -int main(void) -{ - int result = CMCHashMap() + CMCHashMapIter(); - - printf(" +---------------------------------------------------------------+"); - printf("\n"); - printf(" | CMCHashMap Suit : %-46s |\n", result == 0 ? "PASSED" : "FAILED"); - printf(" +---------------------------------------------------------------+"); - printf("\n\n\n"); - - return result; -} -#endif - -#endif /* CMC_TESTS_UNT_CMC_ASHMAP_H */ diff --git a/tests/unt/unt_cmc_hashmultimap.h b/tests/unt/unt_cmc_hashmultimap.h deleted file mode 100644 index 879e833..0000000 --- a/tests/unt/unt_cmc_hashmultimap.h +++ /dev/null @@ -1,1024 +0,0 @@ -#ifndef CMC_TESTS_UNT_CMC_ASHMULTIMAP_H -#define CMC_TESTS_UNT_CMC_ASHMULTIMAP_H - -#include "utl.h" - -#include "tst_cmc_hashmultimap.h" - -struct hashmultimap_fkey *hmm_fkey = &(struct hashmultimap_fkey){ - .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp -}; - -struct hashmultimap_fval *hmm_fval = &(struct hashmultimap_fval){ - .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp -}; - -struct hashmultimap_fkey *hmm_fkey_counter = &(struct hashmultimap_fkey){ - .cmp = k_c_cmp, .cpy = k_c_cpy, .str = k_c_str, .free = k_c_free, .hash = k_c_hash, .pri = k_c_pri -}; - -struct hashmultimap_fval *hmm_fval_counter = &(struct hashmultimap_fval){ - .cmp = v_c_cmp, .cpy = v_c_cpy, .str = v_c_str, .free = v_c_free, .hash = v_c_hash, .pri = v_c_pri -}; - -struct cmc_alloc_node *hmm_alloc_node = - &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free }; - -CMC_CREATE_UNIT(CMCHashMultiMap, true, { - CMC_CREATE_TEST(PFX##_new(), { - struct hashmultimap *map = hmm_new(943722, 0.6, hmm_fkey, hmm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - cmc_assert_not_equals(ptr, NULL, map->buffer); - cmc_assert_equals(size_t, 0, map->count); - cmc_assert_equals(double, 0.6, map->load); - cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag); - cmc_assert_equals(ptr, hmm_fkey, map->f_key); - cmc_assert_equals(ptr, hmm_fval, map->f_val); - cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, map->alloc->malloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, map->alloc->calloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, map->alloc->realloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.free, map->alloc->free); - cmc_assert_equals(ptr, NULL, map->callbacks); - - cmc_assert_greater_equals(size_t, (943722 / 0.6), hmm_capacity(map)); - - hmm_free(map); - - map = hmm_new(100, 0.6, hmm_fkey, hmm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 0; i < map->capacity; i++) - { - cmc_assert_equals(ptr, NULL, map->buffer[i][0]); - cmc_assert_equals(ptr, NULL, map->buffer[i][1]); - } - - hmm_free(map); - - map = hmm_new(0, 0.6, hmm_fkey, hmm_fval); - cmc_assert_equals(ptr, NULL, map); - - map = hmm_new(UINT64_MAX, 0.99, hmm_fkey, hmm_fval); - cmc_assert_equals(ptr, NULL, map); - - map = hmm_new(1000, 0.6, hmm_fkey, NULL); - cmc_assert_equals(ptr, NULL, map); - - map = hmm_new(1000, 0.6, NULL, hmm_fval); - cmc_assert_equals(ptr, NULL, map); - - map = hmm_new(1000, 0.6, NULL, NULL); - cmc_assert_equals(ptr, NULL, map); - }); - - CMC_CREATE_TEST(PFX##_new_custom(), { - struct hashmultimap *map = hmm_new_custom(943722, 0.6, hmm_fkey, hmm_fval, hmm_alloc_node, callbacks); - - cmc_assert_not_equals(ptr, NULL, map); - cmc_assert_not_equals(ptr, NULL, map->buffer); - cmc_assert_equals(size_t, 0, map->count); - cmc_assert_equals(double, 0.6, map->load); - cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag); - cmc_assert_equals(ptr, hmm_fkey, map->f_key); - cmc_assert_equals(ptr, hmm_fval, map->f_val); - cmc_assert_equals(ptr, hmm_alloc_node, map->alloc); - cmc_assert_equals(ptr, callbacks, map->callbacks); - - cmc_assert_greater_equals(size_t, (943722 / 0.6), hmm_capacity(map)); - - hmm_free(map); - - map = hmm_new_custom(0, 0.6, hmm_fkey, hmm_fval, NULL, NULL); - cmc_assert_equals(ptr, NULL, map); - - map = hmm_new_custom(UINT64_MAX, 0.99, hmm_fkey, hmm_fval, NULL, NULL); - cmc_assert_equals(ptr, NULL, map); - - map = hmm_new_custom(1000, 0.6, hmm_fkey, NULL, NULL, NULL); - cmc_assert_equals(ptr, NULL, map); - - map = hmm_new_custom(1000, 0.6, NULL, hmm_fval, NULL, NULL); - cmc_assert_equals(ptr, NULL, map); - - map = hmm_new_custom(1000, 0.6, NULL, NULL, NULL, NULL); - cmc_assert_equals(ptr, NULL, map); - }); - - CMC_CREATE_TEST(PFX##_clear(), { - k_total_free = 0; - v_total_free = 0; - struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey_counter, hmm_fval_counter); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 1; i <= 1000; i++) - hmm_insert(map, i, i); - - cmc_assert_equals(size_t, 1000, map->count); - - map->flag = CMC_FLAG_ERROR; - hmm_clear(map); - - cmc_assert_equals(size_t, 0, map->count); - cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag); - cmc_assert_equals(int32_t, 1000, k_total_free); - cmc_assert_equals(int32_t, 1000, v_total_free); - - hmm_free(map); - k_total_free = 0; - v_total_free = 0; - }); - - CMC_CREATE_TEST(PFX##_free(), { - k_total_free = 0; - v_total_free = 0; - struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey_counter, hmm_fval_counter); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 1; i <= 1000; i++) - hmm_insert(map, i, i); - - cmc_assert_equals(size_t, 1000, map->count); - - hmm_free(map); - - cmc_assert_equals(int32_t, 1000, k_total_free); - cmc_assert_equals(int32_t, 1000, v_total_free); - - map = hmm_new(1000, 0.6, hmm_fkey_counter, hmm_fval_counter); - - cmc_assert_not_equals(ptr, NULL, map); - cmc_assert_not_equals(ptr, NULL, map->buffer); - - hmm_free(map); - - cmc_assert_equals(int32_t, 1000, k_total_free); - cmc_assert_equals(int32_t, 1000, v_total_free); - k_total_free = 0; - v_total_free = 0; - }); - - CMC_CREATE_TEST(insert[count], { - struct hashmultimap *map = hmm_new(100, 0.8, hmm_fkey, hmm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 0; i < 100; i++) - cmc_assert(hmm_insert(map, i % 20, i % 20)); - - cmc_assert_equals(size_t, 100, hmm_count(map)); - - hmm_free(map); - }); - - CMC_CREATE_TEST(PFX##_remove(), { - struct hashmultimap *map = hmm_new(100, 0.8, hmm_fkey, hmm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 0; i < 200; i++) - cmc_assert(hmm_insert(map, i % 20, i % 20)); - - size_t r; - - for (size_t i = 0; i < 60; i++) - cmc_assert(hmm_remove(map, i % 20, &r)); - - cmc_assert_equals(size_t, 140, hmm_count(map)); - - hmm_free(map); - - // count = 0 - map = hmm_new(100, 0.8, hmm_fkey, hmm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert(!hmm_remove(map, 10, &r)); - - hmm_free(map); - - // count = 1 - map = hmm_new(100, 0.8, hmm_fkey, hmm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - cmc_assert(hmm_insert(map, 10, 11)); - cmc_assert(hmm_remove(map, 10, &r)); - - hmm_free(map); - }); - - CMC_CREATE_TEST(get[key ordering], { - struct hashmultimap *map = hmm_new(100, 0.8, hmm_fkey, hmm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - /* Assert that the value 100 is accessed before the value 101 for */ - /* the same key */ - cmc_assert(hmm_insert(map, 10, 100)); - cmc_assert(hmm_insert(map, 20, 102)); - cmc_assert(hmm_insert(map, 10, 101)); - - cmc_assert_equals(size_t, 100, hmm_get(map, 10)); - - hmm_free(map); - }); - - CMC_CREATE_TEST(PFX##_max(), { - struct hashmultimap *map = hmm_new(50, 0.8, hmm_fkey, hmm_fval); - - size_t max_key; - size_t max_val; - cmc_assert(!hmm_max(map, &max_key, &max_val)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, map->flag); - - cmc_assert(hmm_insert(map, 1, 2)); - cmc_assert(hmm_max(map, &max_key, &max_val)); - cmc_assert_equals(size_t, 1, max_key); - cmc_assert_equals(size_t, 2, max_val); - - cmc_assert(hmm_insert(map, 2, 3)); - cmc_assert(hmm_insert(map, 0, 1)); - cmc_assert(hmm_max(map, &max_key, &max_val)); - cmc_assert_equals(size_t, 2, max_key); - cmc_assert_equals(size_t, 3, max_val); - - for (size_t i = 3; i <= 100; i++) - { - cmc_assert(hmm_insert(map, i, i)); - } - - cmc_assert(hmm_max(map, &max_key, &max_val)); - cmc_assert_equals(size_t, 100, max_key); - cmc_assert_equals(size_t, 100, max_val); - - hmm_free(map); - }); - - CMC_CREATE_TEST(PFX##_min(), { - struct hashmultimap *map = hmm_new(50, 0.8, hmm_fkey, hmm_fval); - - size_t min_key; - size_t min_val; - cmc_assert(!hmm_min(map, &min_key, &min_val)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, map->flag); - - cmc_assert(hmm_insert(map, 1, 2)); - cmc_assert(hmm_min(map, &min_key, &min_val)); - cmc_assert_equals(size_t, 1, min_key); - cmc_assert_equals(size_t, 2, min_val); - - cmc_assert(hmm_insert(map, 2, 3)); - cmc_assert(hmm_insert(map, 0, 1)); - cmc_assert(hmm_min(map, &min_key, &min_val)); - cmc_assert_equals(size_t, 0, min_key); - cmc_assert_equals(size_t, 1, min_val); - - for (size_t i = 3; i <= 100; i++) - { - cmc_assert(hmm_insert(map, i, i)); - } - - cmc_assert(hmm_min(map, &min_key, &min_val)); - cmc_assert_equals(size_t, 0, min_key); - cmc_assert_equals(size_t, 1, min_val); - - hmm_free(map); - }); - - CMC_CREATE_TEST(PFX##_copy_of(), { - struct hashmultimap *map = hmm_new(100, 0.8, hmm_fkey, hmm_fval); - - for (size_t i = 0; i < 1000; i++) - hmm_insert(map, i, i); - - struct hashmultimap *map2 = hmm_copy_of(map); - - cmc_assert_equals(size_t, map->count, map2->count); - cmc_assert(hmm_equals(map, map2)); - - hmm_free(map); - }); - - CMC_CREATE_TEST(PFX##_equals(), { - struct hashmultimap *map1 = hmm_new(100, 0.8, hmm_fkey, hmm_fval); - struct hashmultimap *map2 = hmm_new(100, 0.8, hmm_fkey, hmm_fval); - - cmc_assert(hmm_equals(map1, map2)); - - cmc_assert(hmm_insert(map1, 1, 1)); - cmc_assert(hmm_insert(map2, 1, 1)); - cmc_assert(hmm_equals(map1, map2)); - - for (size_t i = 2; i < 200; i++) - { - cmc_assert(hmm_insert(map1, i, i) && hmm_insert(map2, i, i)); - } - - cmc_assert(hmm_equals(map1, map2)); - - hmm_free(map1); - hmm_free(map2); - }); - - CMC_CREATE_TEST(key_count, { - struct hashmultimap *map = hmm_new(50, 0.8, hmm_fkey, hmm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 0; i < 1000; i++) - cmc_assert(hmm_insert(map, i % 20, i % 20)); - - cmc_assert_equals(size_t, 1000, hmm_count(map)); - - for (size_t i = 0; i < 20; i++) - cmc_assert_equals(size_t, 50, hmm_key_count(map, i)); - - hmm_free(map); - }); - - CMC_CREATE_TEST(flags, { - struct hashmultimap *map = hmm_new(100, 0.8, hmm_fkey, hmm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map)); - - // clear - map->flag = CMC_FLAG_ERROR; - hmm_clear(map); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map)); - - // customize - map->flag = CMC_FLAG_ERROR; - hmm_customize(map, NULL, NULL); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map)); - - // insert - map->flag = CMC_FLAG_ERROR; - cmc_assert(hmm_insert(map, 1, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map)); - - // update - cmc_assert(!hmm_update(map, 9, 10, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hmm_flag(map)); - - cmc_assert(hmm_update(map, 1, 20, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map)); - - // update_all - map->flag = CMC_FLAG_ERROR; - cmc_assert_equals(size_t, 1, hmm_update_all(map, 1, 2, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map)); - - map->flag = CMC_FLAG_ERROR; - cmc_assert_equals(size_t, 0, hmm_update_all(map, 2, 4, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hmm_flag(map)); - - hmm_clear(map); - cmc_assert_equals(size_t, 0, hmm_update_all(map, 1, 2, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hmm_flag(map)); - - // remove - map->flag = CMC_FLAG_ERROR; - cmc_assert(!hmm_remove(map, 1, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hmm_flag(map)); - - cmc_assert(hmm_insert(map, 1, 1)); - cmc_assert(!hmm_remove(map, 2, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hmm_flag(map)); - - cmc_assert(hmm_remove(map, 1, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map)); - - // remove_all - cmc_assert(!hmm_remove_all(map, 1, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hmm_flag(map)); - - cmc_assert(hmm_insert(map, 1, 1) && hmm_insert(map, 1, 1)); - cmc_assert_equals(size_t, 0, hmm_remove_all(map, 2, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hmm_flag(map)); - - cmc_assert_equals(size_t, 2, hmm_remove_all(map, 1, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map)); - - // max min - cmc_assert(!hmm_max(map, NULL, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hmm_flag(map)); - map->flag = CMC_FLAG_ERROR; - cmc_assert(!hmm_min(map, NULL, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hmm_flag(map)); - - cmc_assert(hmm_insert(map, 1, 1)); - cmc_assert(hmm_max(map, NULL, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map)); - map->flag = CMC_FLAG_ERROR; - cmc_assert(hmm_min(map, NULL, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map)); - - // get get_ref - hmm_get(map, 2); - cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hmm_flag(map)); - map->flag = CMC_FLAG_ERROR; - hmm_get_ref(map, 2); - cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hmm_flag(map)); - - hmm_get(map, 1); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map)); - map->flag = CMC_FLAG_ERROR; - hmm_get_ref(map, 1); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map)); - - hmm_clear(map); - hmm_get(map, 1); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hmm_flag(map)); - map->flag = CMC_FLAG_ERROR; - hmm_get_ref(map, 1); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hmm_flag(map)); - - // contains - map->flag = CMC_FLAG_ERROR; - cmc_assert(!hmm_contains(map, 1000)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map)); - - // copy_of - map->flag = CMC_FLAG_ERROR; - struct hashmultimap *map2 = hmm_copy_of(map); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map2)); - - // equals - map->flag = CMC_FLAG_ERROR; - map2->flag = CMC_FLAG_ERROR; - cmc_assert(hmm_equals(map, map2)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map2)); - - hmm_free(map); - hmm_free(map2); - }); - - CMC_CREATE_TEST(callbacks, { - struct hashmultimap *map = hmm_new_custom(100, 0.8, hmm_fkey, hmm_fval, NULL, callbacks); - - cmc_assert_not_equals(ptr, NULL, map); - - total_create = 0; - total_read = 0; - total_update = 0; - total_delete = 0; - total_resize = 0; - - cmc_assert(hmm_insert(map, 1, 1)); - cmc_assert_equals(int32_t, 1, total_create); - - cmc_assert(hmm_update(map, 1, 2, NULL)); - cmc_assert_equals(int32_t, 1, total_update); - - cmc_assert(hmm_insert(map, 1, 1)); - cmc_assert_equals(int32_t, 2, total_create); - - cmc_assert_equals(size_t, 2, hmm_update_all(map, 1, 3, NULL)); - cmc_assert_equals(int32_t, 2, total_update); - - cmc_assert(hmm_remove(map, 1, NULL)); - cmc_assert_equals(int32_t, 1, total_delete); - - cmc_assert(hmm_insert(map, 1, 2)); - cmc_assert_equals(int32_t, 3, total_create); - - cmc_assert_equals(size_t, 2, hmm_remove_all(map, 1, NULL)); - cmc_assert_equals(int32_t, 2, total_delete); - - cmc_assert(hmm_insert(map, 1, 2)); - cmc_assert_equals(int32_t, 4, total_create); - - cmc_assert(hmm_max(map, NULL, NULL)); - cmc_assert_equals(int32_t, 1, total_read); - - cmc_assert(hmm_min(map, NULL, NULL)); - cmc_assert_equals(int32_t, 2, total_read); - - cmc_assert_equals(size_t, 2, hmm_get(map, 1)); - cmc_assert_equals(int32_t, 3, total_read); - - cmc_assert_not_equals(ptr, NULL, hmm_get_ref(map, 1)); - cmc_assert_equals(int32_t, 4, total_read); - - cmc_assert(hmm_contains(map, 1)); - cmc_assert_equals(int32_t, 5, total_read); - - cmc_assert(hmm_resize(map, 1000)); - cmc_assert_equals(int32_t, 1, total_resize); - - cmc_assert(hmm_resize(map, 100)); - cmc_assert_equals(int32_t, 2, total_resize); - - cmc_assert_equals(int32_t, 4, total_create); - cmc_assert_equals(int32_t, 5, total_read); - cmc_assert_equals(int32_t, 2, total_update); - cmc_assert_equals(int32_t, 2, total_delete); - cmc_assert_equals(int32_t, 2, total_resize); - - hmm_customize(map, NULL, NULL); - - cmc_assert_equals(ptr, NULL, map->callbacks); - - hmm_clear(map); - cmc_assert(hmm_insert(map, 1, 1)); - cmc_assert(hmm_update(map, 1, 2, NULL)); - cmc_assert(hmm_insert(map, 1, 1)); - cmc_assert_equals(size_t, 2, hmm_update_all(map, 1, 3, NULL)); - cmc_assert(hmm_remove(map, 1, NULL)); - cmc_assert(hmm_insert(map, 1, 2)); - cmc_assert_equals(size_t, 2, hmm_remove_all(map, 1, NULL)); - cmc_assert(hmm_insert(map, 1, 2)); - cmc_assert(hmm_max(map, NULL, NULL)); - cmc_assert(hmm_min(map, NULL, NULL)); - cmc_assert_equals(size_t, 2, hmm_get(map, 1)); - cmc_assert_not_equals(ptr, NULL, hmm_get_ref(map, 1)); - cmc_assert(hmm_contains(map, 1)); - cmc_assert(hmm_resize(map, 1000)); - cmc_assert(hmm_resize(map, 100)); - - cmc_assert_equals(int32_t, 4, total_create); - cmc_assert_equals(int32_t, 5, total_read); - cmc_assert_equals(int32_t, 2, total_update); - cmc_assert_equals(int32_t, 2, total_delete); - cmc_assert_equals(int32_t, 2, total_resize); - - cmc_assert_equals(ptr, NULL, map->callbacks); - - hmm_free(map); - - total_create = 0; - total_read = 0; - total_update = 0; - total_delete = 0; - total_resize = 0; - }); -}); - -struct hashmultimap_fkey *hmm_fkey_numhash = &(struct hashmultimap_fkey){ - .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = numhash, .pri = cmc_size_cmp -}; - -CMC_CREATE_UNIT(CMCHashMultiMapIter, true, { - CMC_CREATE_TEST(PFX##_iter_start(), { - struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct hashmultimap_iter it = hmm_iter_start(map); - - cmc_assert_equals(ptr, map, it.target); - cmc_assert_equals(size_t, 0, it.cursor); - cmc_assert_equals(size_t, 0, it.index); - cmc_assert_equals(size_t, 0, it.first); - cmc_assert_equals(size_t, 0, it.last); - cmc_assert_equals(bool, true, it.start); - cmc_assert_equals(bool, true, it.end); - - cmc_assert(hmm_iter_at_start(&it)); - cmc_assert(hmm_iter_at_end(&it)); - - cmc_assert(hmm_insert(map, 1, 1)); - cmc_assert(hmm_insert(map, 2, 2)); - cmc_assert(hmm_insert(map, 3, 3)); - - it = hmm_iter_start(map); - - cmc_assert_equals(size_t, 0, it.index); - - cmc_assert_equals(size_t, 1, it.cursor); - cmc_assert_equals(size_t, 1, it.first); - cmc_assert_equals(size_t, 3, it.last); - cmc_assert_equals(bool, false, it.end); - - hmm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_end(), { - struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct hashmultimap_iter it = hmm_iter_end(map); - - cmc_assert_equals(ptr, map, it.target); - cmc_assert_equals(size_t, 0, it.cursor); - cmc_assert_equals(size_t, 0, it.index); - cmc_assert_equals(size_t, 0, it.first); - cmc_assert_equals(size_t, 0, it.last); - cmc_assert_equals(bool, true, it.start); - cmc_assert_equals(bool, true, it.end); - - cmc_assert(hmm_iter_at_start(&it)); - cmc_assert(hmm_iter_at_end(&it)); - - cmc_assert(hmm_insert(map, 1, 1)); - cmc_assert(hmm_insert(map, 2, 2)); - cmc_assert(hmm_insert(map, 3, 3)); - - it = hmm_iter_end(map); - - cmc_assert_equals(size_t, map->count - 1, it.index); - - cmc_assert_equals(size_t, 3, it.cursor); - cmc_assert_equals(size_t, 1, it.first); - cmc_assert_equals(size_t, 3, it.last); - cmc_assert_equals(bool, false, it.start); - - hmm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_at_start(), { - struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey, hmm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct hashmultimap_iter it = hmm_iter_start(map); - - // Empty checks - cmc_assert(hmm_iter_at_start(&it)); - it = hmm_iter_end(map); - cmc_assert(hmm_iter_at_start(&it)); - - // Non-empty checks - cmc_assert(hmm_insert(map, 1, 1)); - cmc_assert(hmm_insert(map, 2, 2)); - it = hmm_iter_end(map); - cmc_assert(!hmm_iter_at_start(&it)); - it = hmm_iter_start(map); - cmc_assert(hmm_iter_at_start(&it)); - - hmm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_at_end(), { - struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey, hmm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct hashmultimap_iter it = hmm_iter_start(map); - - // Empty check - cmc_assert(hmm_iter_at_end(&it)); - it = hmm_iter_end(map); - cmc_assert(hmm_iter_at_end(&it)); - - // Non-empty checks - cmc_assert(hmm_insert(map, 1, 1)); - cmc_assert(hmm_insert(map, 2, 2)); - it = hmm_iter_end(map); - cmc_assert(hmm_iter_at_end(&it)); - it = hmm_iter_start(map); - cmc_assert(!hmm_iter_at_end(&it)); - - hmm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_to_start(), { - struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct hashmultimap_iter it = hmm_iter_start(map); - - cmc_assert(!hmm_iter_to_start(&it)); - - for (size_t i = 1; i <= 100; i++) - hmm_insert(map, i, i); - - cmc_assert_equals(size_t, 100, map->count); - - it = hmm_iter_end(map); - - cmc_assert(!hmm_iter_at_start(&it)); - cmc_assert(hmm_iter_at_end(&it)); - - cmc_assert_equals(size_t, 100, hmm_iter_value(&it)); - - cmc_assert(hmm_iter_to_start(&it)); - - cmc_assert(hmm_iter_at_start(&it)); - cmc_assert(!hmm_iter_at_end(&it)); - - cmc_assert_equals(size_t, 1, hmm_iter_value(&it)); - - hmm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_to_end(), { - struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct hashmultimap_iter it = hmm_iter_end(map); - - cmc_assert(!hmm_iter_to_end(&it)); - - for (size_t i = 1; i <= 100; i++) - hmm_insert(map, i, i); - - it = hmm_iter_start(map); - - cmc_assert(hmm_iter_at_start(&it)); - cmc_assert(!hmm_iter_at_end(&it)); - - cmc_assert_equals(size_t, 1, hmm_iter_value(&it)); - - cmc_assert(hmm_iter_to_end(&it)); - - cmc_assert(!hmm_iter_at_start(&it)); - cmc_assert(hmm_iter_at_end(&it)); - - cmc_assert_equals(size_t, 100, hmm_iter_value(&it)); - - hmm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_next(), { - struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey, hmm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct hashmultimap_iter it = hmm_iter_start(map); - - cmc_assert(!hmm_iter_next(&it)); - - for (size_t i = 1; i <= 1000; i++) - hmm_insert(map, i, i); - - size_t sum = 0; - for (it = hmm_iter_start(map); !hmm_iter_at_end(&it); hmm_iter_next(&it)) - { - sum += hmm_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - - hmm_iter_to_start(&it); - do - { - sum += hmm_iter_value(&it); - } while (hmm_iter_next(&it)); - - cmc_assert_equals(size_t, 500500, sum); - - hmm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_prev(), { - struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey, hmm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct hashmultimap_iter it = hmm_iter_end(map); - - cmc_assert(!hmm_iter_prev(&it)); - - for (size_t i = 1; i <= 1000; i++) - hmm_insert(map, i, i); - - size_t sum = 0; - for (it = hmm_iter_end(map); !hmm_iter_at_start(&it); hmm_iter_prev(&it)) - { - sum += hmm_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - - hmm_iter_to_end(&it); - do - { - sum += hmm_iter_value(&it); - } while (hmm_iter_prev(&it)); - - cmc_assert_equals(size_t, 500500, sum); - - hmm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_advance(), { - struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct hashmultimap_iter it = hmm_iter_start(map); - - cmc_assert(!hmm_iter_advance(&it, 1)); - - for (size_t i = 0; i <= 1000; i++) - hmm_insert(map, i, i); - - it = hmm_iter_start(map); - - cmc_assert(!hmm_iter_advance(&it, 0)); - cmc_assert(!hmm_iter_advance(&it, map->count)); - - size_t sum = 0; - for (it = hmm_iter_start(map);;) - { - sum += hmm_iter_value(&it); - - if (!hmm_iter_advance(&it, 2)) - break; - } - - cmc_assert_equals(size_t, 250500, sum); - - hmm_iter_to_start(&it); - cmc_assert(hmm_iter_advance(&it, map->count - 1)); - - hmm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_rewind(), { - struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct hashmultimap_iter it = hmm_iter_end(map); - - cmc_assert(!hmm_iter_rewind(&it, 1)); - - for (size_t i = 0; i <= 1000; i++) - hmm_insert(map, i, i); - - it = hmm_iter_end(map); - - cmc_assert(!hmm_iter_rewind(&it, 0)); - cmc_assert(!hmm_iter_rewind(&it, map->count)); - - size_t sum = 0; - for (it = hmm_iter_end(map);;) - { - sum += hmm_iter_value(&it); - - if (!hmm_iter_rewind(&it, 2)) - break; - } - - cmc_assert_equals(size_t, 250500, sum); - - hmm_iter_to_end(&it); - cmc_assert(hmm_iter_rewind(&it, map->count - 1)); - - hmm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_go_to(), { - struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct hashmultimap_iter it = hmm_iter_end(map); - cmc_assert(!hmm_iter_go_to(&it, 0)); - - it = hmm_iter_start(map); - cmc_assert(!hmm_iter_go_to(&it, 0)); - - for (size_t i = 0; i <= 1000; i++) - hmm_insert(map, i, i); - - it = hmm_iter_start(map); - - size_t sum = 0; - for (size_t i = 0; i < 1001; i++) - { - hmm_iter_go_to(&it, i); - - sum += hmm_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - for (size_t i = 1001; i > 0; i--) - { - cmc_assert(hmm_iter_go_to(&it, i - 1)); - - sum += hmm_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - for (size_t i = 0; i < 1001; i += 100) - { - cmc_assert(hmm_iter_go_to(&it, i)); - cmc_assert_equals(size_t, i, hmm_iter_index(&it)); - - sum += hmm_iter_value(&it); - } - - cmc_assert_equals(size_t, 5500, sum); - - hmm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_key(), { - struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey, hmm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct hashmultimap_iter it = hmm_iter_end(map); - - cmc_assert_equals(size_t, (size_t){ 0 }, hmm_iter_key(&it)); - - cmc_assert(hmm_insert(map, 10, 10)); - - it = hmm_iter_start(map); - - cmc_assert_equals(size_t, 10, hmm_iter_key(&it)); - - hmm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_value(), { - struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey, hmm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct hashmultimap_iter it = hmm_iter_end(map); - - cmc_assert_equals(size_t, (size_t){ 0 }, hmm_iter_value(&it)); - - cmc_assert(hmm_insert(map, 10, 10)); - - it = hmm_iter_start(map); - - cmc_assert_equals(size_t, 10, hmm_iter_value(&it)); - - hmm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_rvalue(), { - struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey, hmm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct hashmultimap_iter it = hmm_iter_end(map); - - cmc_assert_equals(ptr, NULL, hmm_iter_rvalue(&it)); - - cmc_assert(hmm_insert(map, 10, 10)); - - it = hmm_iter_start(map); - - cmc_assert_not_equals(ptr, NULL, hmm_iter_rvalue(&it)); - cmc_assert_equals(size_t, 10, *hmm_iter_rvalue(&it)); - - hmm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_index(), { - struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey, hmm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 0; i <= 1000; i++) - hmm_insert(map, i, i); - - struct hashmultimap_iter it = hmm_iter_start(map); - - for (size_t i = 0; i < 1001; i++) - { - cmc_assert_equals(size_t, i, hmm_iter_index(&it)); - hmm_iter_next(&it); - } - - it = hmm_iter_end(map); - for (size_t i = 1001; i > 0; i--) - { - cmc_assert_equals(size_t, i - 1, hmm_iter_index(&it)); - hmm_iter_prev(&it); - } - - hmm_free(map); - }); -}); - -#ifdef CMC_TEST_MAIN -int main(void) -{ - int result = CMCHashMultiMap() + CMCHashMultiMapIter(); - - printf(" +---------------------------------------------------------------+"); - printf("\n"); - printf(" | CMCHashMultiMap Suit : %-41s |\n", result == 0 ? "PASSED" : "FAILED"); - printf(" +---------------------------------------------------------------+"); - printf("\n\n\n"); - - return result; -} -#endif - -#endif /* CMC_TESTS_UNT_CMC_ASHMULTIMAP_H */ diff --git a/tests/unt/unt_cmc_hashmultiset.h b/tests/unt/unt_cmc_hashmultiset.h deleted file mode 100644 index 54f3922..0000000 --- a/tests/unt/unt_cmc_hashmultiset.h +++ /dev/null @@ -1,864 +0,0 @@ -#ifndef CMC_TESTS_UNT_CMC_ASHMULTISET_H -#define CMC_TESTS_UNT_CMC_ASHMULTISET_H - -#include "utl.h" - -#include "tst_cmc_hashmultiset.h" - -struct hashmultiset_fval *hms_fval = &(struct hashmultiset_fval){ - .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp -}; - -struct hashmultiset_fval *hms_fval_counter = &(struct hashmultiset_fval){ - .cmp = v_c_cmp, .cpy = v_c_cpy, .str = v_c_str, .free = v_c_free, .hash = v_c_hash, .pri = v_c_pri -}; - -struct cmc_alloc_node *hms_alloc_node = - &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free }; - -CMC_CREATE_UNIT(CMCHashMultiSet, true, { - CMC_CREATE_TEST(PFX##_new(), { - struct hashmultiset *set = hms_new(943722, 0.6, hms_fval); - - cmc_assert_not_equals(ptr, NULL, set); - cmc_assert_not_equals(ptr, NULL, set->buffer); - cmc_assert_equals(size_t, 0, set->count); - cmc_assert_equals(double, 0.6, set->load); - cmc_assert_equals(int32_t, CMC_FLAG_OK, set->flag); - cmc_assert_equals(ptr, hms_fval, set->f_val); - cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, set->alloc->malloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, set->alloc->calloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, set->alloc->realloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.free, set->alloc->free); - cmc_assert_equals(ptr, NULL, set->callbacks); - - cmc_assert_greater_equals(size_t, (943722 / 0.6), hms_capacity(set)); - - hms_free(set); - - set = hms_new(0, 0.6, hms_fval); - cmc_assert_equals(ptr, NULL, set); - - set = hms_new(UINT64_MAX, 0.99, hms_fval); - cmc_assert_equals(ptr, NULL, set); - - set = hms_new(1000, 0.6, NULL); - cmc_assert_equals(ptr, NULL, set); - - set = hms_new(1000, 0.6, NULL); - cmc_assert_equals(ptr, NULL, set); - }); - - CMC_CREATE_TEST(PFX##_new_custom(), { - struct hashmultiset *set = hms_new_custom(943722, 0.6, hms_fval, hms_alloc_node, callbacks); - - cmc_assert_not_equals(ptr, NULL, set); - cmc_assert_not_equals(ptr, NULL, set->buffer); - cmc_assert_equals(size_t, 0, set->count); - cmc_assert_equals(double, 0.6, set->load); - cmc_assert_equals(int32_t, CMC_FLAG_OK, set->flag); - cmc_assert_equals(ptr, hms_fval, set->f_val); - cmc_assert_equals(ptr, hms_alloc_node, set->alloc); - cmc_assert_equals(ptr, callbacks, set->callbacks); - - cmc_assert_greater_equals(size_t, (943722 / 0.6), hms_capacity(set)); - - hms_free(set); - - set = hms_new_custom(0, 0.6, hms_fval, NULL, NULL); - cmc_assert_equals(ptr, NULL, set); - - set = hms_new_custom(UINT64_MAX, 0.99, hms_fval, NULL, NULL); - cmc_assert_equals(ptr, NULL, set); - - set = hms_new_custom(1000, 0.6, NULL, NULL, NULL); - cmc_assert_equals(ptr, NULL, set); - }); - - CMC_CREATE_TEST(PFX##_clear(), { - v_total_free = 0; - struct hashmultiset *set = hms_new(100, 0.6, hms_fval_counter); - - cmc_assert_not_equals(ptr, NULL, set); - - for (size_t i = 1; i <= 1000; i++) - hms_insert(set, i); - - cmc_assert_equals(size_t, 1000, set->count); - - set->flag = CMC_FLAG_ERROR; - hms_clear(set); - - cmc_assert_equals(size_t, 0, set->count); - cmc_assert_equals(int32_t, CMC_FLAG_OK, set->flag); - cmc_assert_equals(int32_t, 1000, v_total_free); - - hms_free(set); - v_total_free = 0; - }); - - CMC_CREATE_TEST(PFX##_free(), { - v_total_free = 0; - struct hashmultiset *set = hms_new(100, 0.6, hms_fval_counter); - - cmc_assert_not_equals(ptr, NULL, set); - - for (size_t i = 1; i <= 1000; i++) - hms_insert(set, i); - - cmc_assert_equals(size_t, 1000, set->count); - - hms_free(set); - - cmc_assert_equals(int32_t, 1000, v_total_free); - - set = hms_new(1000, 0.6, hms_fval_counter); - - cmc_assert_not_equals(ptr, NULL, set); - cmc_assert_not_equals(ptr, NULL, set->buffer); - - hms_free(set); - - cmc_assert_equals(int32_t, 1000, v_total_free); - v_total_free = 0; - }); - - CMC_CREATE_TEST(insert[count cardinality multiplicity], { - struct hashmultiset *set = hms_new(100, 0.6, hms_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - cmc_assert(hms_insert(set, 1)); - cmc_assert(hms_insert(set, 2)); - cmc_assert(hms_insert(set, 2)); - cmc_assert(hms_insert(set, 3)); - cmc_assert(hms_insert(set, 3)); - cmc_assert(hms_insert(set, 3)); - - cmc_assert_equals(size_t, 3, hms_count(set)); - cmc_assert_equals(size_t, 6, hms_cardinality(set)); - - for (size_t i = 0; i <= 3; i++) - cmc_assert_equals(size_t, i, hms_multiplicity_of(set, i)); - - hms_free(set); - }); - - CMC_CREATE_TEST(remove[count cardinality multiplicity], { - struct hashmultiset *set = hms_new(100, 0.6, hms_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - cmc_assert(hms_insert(set, 1)); - cmc_assert(hms_insert(set, 2)); - cmc_assert(hms_insert(set, 2)); - cmc_assert(hms_insert(set, 3)); - cmc_assert(hms_insert(set, 3)); - cmc_assert(hms_insert(set, 3)); - - cmc_assert_equals(size_t, 3, hms_count(set)); - cmc_assert_equals(size_t, 6, hms_cardinality(set)); - - for (size_t i = 0; i <= 3; i++) - cmc_assert_equals(size_t, i, hms_multiplicity_of(set, i)); - - cmc_assert(hms_remove(set, 1)); - cmc_assert(hms_remove(set, 2)); - cmc_assert(hms_remove(set, 3)); - - cmc_assert_equals(size_t, 2, hms_count(set)); - cmc_assert_equals(size_t, 3, hms_cardinality(set)); - - cmc_assert_equals(size_t, 0, hms_multiplicity_of(set, 0)); - cmc_assert_equals(size_t, 0, hms_multiplicity_of(set, 1)); - cmc_assert_equals(size_t, 1, hms_multiplicity_of(set, 2)); - cmc_assert_equals(size_t, 2, hms_multiplicity_of(set, 3)); - - hms_free(set); - }); - - CMC_CREATE_TEST(remove_all[count cardinality multiplicity], { - struct hashmultiset *set = hms_new(100, 0.6, hms_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - cmc_assert(hms_insert(set, 1)); - cmc_assert(hms_insert(set, 2)); - cmc_assert(hms_insert(set, 2)); - cmc_assert(hms_insert(set, 3)); - cmc_assert(hms_insert(set, 3)); - cmc_assert(hms_insert(set, 3)); - - cmc_assert_equals(size_t, 3, hms_count(set)); - cmc_assert_equals(size_t, 6, hms_cardinality(set)); - - for (size_t i = 0; i <= 3; i++) - cmc_assert_equals(size_t, i, hms_multiplicity_of(set, i)); - - cmc_assert(hms_remove_all(set, 1)); - cmc_assert(hms_remove_all(set, 3)); - - cmc_assert_equals(size_t, 1, hms_count(set)); - cmc_assert_equals(size_t, 2, hms_cardinality(set)); - - cmc_assert_equals(size_t, 0, hms_multiplicity_of(set, 0)); - cmc_assert_equals(size_t, 0, hms_multiplicity_of(set, 1)); - cmc_assert_equals(size_t, 2, hms_multiplicity_of(set, 2)); - cmc_assert_equals(size_t, 0, hms_multiplicity_of(set, 3)); - - hms_free(set); - }); - - CMC_CREATE_TEST(multiplicity, { - struct hashmultiset *set = hms_new(50, 0.6, hms_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - for (size_t i = 0; i < 1000; i++) - cmc_assert(hms_insert(set, i % 20)); - - cmc_assert_equals(size_t, 20, hms_count(set)); - cmc_assert_equals(size_t, 1000, hms_cardinality(set)); - - for (size_t i = 0; i < 20; i++) - cmc_assert_equals(size_t, 50, hms_multiplicity_of(set, i)); - - hms_free(set); - }); - - CMC_CREATE_TEST(flags, { - struct hashmultiset *set = hms_new(100, 0.6, hms_fval); - - cmc_assert_not_equals(ptr, NULL, set); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set)); - - // clear - set->flag = CMC_FLAG_ERROR; - hms_clear(set); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set)); - - // customize - set->flag = CMC_FLAG_ERROR; - hms_customize(set, NULL, NULL); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set)); - - // insert - set->flag = CMC_FLAG_ERROR; - cmc_assert(hms_insert(set, 10)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set)); - - set->flag = CMC_FLAG_ERROR; - cmc_assert(hms_insert(set, 10)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set)); - - // insert_many - set->flag = CMC_FLAG_ERROR; - cmc_assert(hms_insert_many(set, 1, 0)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set)); - - set->flag = CMC_FLAG_ERROR; - cmc_assert(hms_insert_many(set, 1, 2)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set)); - - // update - set->flag = CMC_FLAG_ERROR; - cmc_assert(hms_update(set, 1, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set)); - - set->flag = CMC_FLAG_ERROR; - cmc_assert(hms_update(set, 10, 0)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set)); - - // remove - cmc_assert(!hms_remove(set, 10)); - cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hms_flag(set)); - - cmc_assert(hms_remove(set, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set)); - - // remove_all - cmc_assert_equals(size_t, 0, hms_remove_all(set, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hms_flag(set)); - - cmc_assert(hms_insert_many(set, 1, 10)); - cmc_assert_equals(size_t, 0, hms_remove_all(set, 10)); - cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hms_flag(set)); - - cmc_assert_equals(size_t, 10, hms_remove_all(set, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set)); - - // max min - cmc_assert(!hms_max(set, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hms_flag(set)); - set->flag = CMC_FLAG_ERROR; - cmc_assert(!hms_min(set, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hms_flag(set)); - - cmc_assert(hms_insert(set, 1)); - set->flag = CMC_FLAG_ERROR; - cmc_assert(hms_max(set, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set)); - set->flag = CMC_FLAG_ERROR; - cmc_assert(hms_min(set, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set)); - - // multiplicity_of - set->flag = CMC_FLAG_ERROR; - cmc_assert_equals(size_t, 0, hms_multiplicity_of(set, 10)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set)); - - // contains - set->flag = CMC_FLAG_ERROR; - cmc_assert(!hms_contains(set, 10)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set)); - - // copy_of - set->flag = CMC_FLAG_ERROR; - struct hashmultiset *set2 = hms_copy_of(set); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set2)); - - // equals - set->flag = CMC_FLAG_ERROR; - set2->flag = CMC_FLAG_ERROR; - cmc_assert(hms_equals(set, set2)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set2)); - - hms_free(set); - hms_free(set2); - }); - - CMC_CREATE_TEST(callbacks, { - struct hashmultiset *set = hms_new_custom(100, 0.8, hms_fval, NULL, callbacks); - - cmc_assert_not_equals(ptr, NULL, set); - - total_create = 0; - total_read = 0; - total_update = 0; - total_delete = 0; - total_resize = 0; - - cmc_assert(hms_insert(set, 1)); - cmc_assert_equals(int32_t, 1, total_create); - - cmc_assert(hms_insert_many(set, 1, 3)); - cmc_assert_equals(int32_t, 2, total_create); - - cmc_assert(hms_update(set, 1, 0)); - cmc_assert_equals(int32_t, 1, total_update); - - cmc_assert(hms_update(set, 1, 10)); - cmc_assert_equals(int32_t, 2, total_update); - - cmc_assert(hms_remove(set, 1)); - cmc_assert_equals(int32_t, 1, total_delete); - - cmc_assert(hms_remove_all(set, 1)); - cmc_assert_equals(int32_t, 2, total_delete); - - cmc_assert(hms_update(set, 1, 10)); - cmc_assert_equals(int32_t, 3, total_update); - - cmc_assert(hms_max(set, NULL)); - cmc_assert_equals(int32_t, 1, total_read); - - cmc_assert(hms_min(set, NULL)); - cmc_assert_equals(int32_t, 2, total_read); - - cmc_assert(hms_contains(set, 1)); - cmc_assert_equals(int32_t, 3, total_read); - - cmc_assert(hms_resize(set, 1000)); - cmc_assert_equals(int32_t, 1, total_resize); - - cmc_assert(hms_resize(set, 100)); - cmc_assert_equals(int32_t, 2, total_resize); - - cmc_assert_equals(int32_t, 2, total_create); - cmc_assert_equals(int32_t, 3, total_read); - cmc_assert_equals(int32_t, 3, total_update); - cmc_assert_equals(int32_t, 2, total_delete); - cmc_assert_equals(int32_t, 2, total_resize); - - hms_customize(set, NULL, NULL); - - cmc_assert_equals(ptr, NULL, set->callbacks); - - hms_clear(set); - cmc_assert(hms_insert(set, 1)); - cmc_assert(hms_insert_many(set, 1, 3)); - cmc_assert(hms_update(set, 1, 0)); - cmc_assert(hms_update(set, 1, 10)); - cmc_assert(hms_remove(set, 1)); - cmc_assert(hms_remove_all(set, 1)); - cmc_assert(hms_update(set, 1, 10)); - cmc_assert(hms_max(set, NULL)); - cmc_assert(hms_min(set, NULL)); - cmc_assert(hms_contains(set, 1)); - cmc_assert(hms_resize(set, 1000)); - cmc_assert(hms_resize(set, 100)); - - cmc_assert_equals(int32_t, 2, total_create); - cmc_assert_equals(int32_t, 3, total_read); - cmc_assert_equals(int32_t, 3, total_update); - cmc_assert_equals(int32_t, 2, total_delete); - cmc_assert_equals(int32_t, 2, total_resize); - - cmc_assert_equals(ptr, NULL, set->callbacks); - - hms_free(set); - - total_create = 0; - total_read = 0; - total_update = 0; - total_delete = 0; - total_resize = 0; - }); -}); - -struct hashmultiset_fval *hms_fval_numhash = &(struct hashmultiset_fval){ - .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = numhash, .pri = cmc_size_cmp -}; - -CMC_CREATE_UNIT(CMCHashMultiSetIter, true, { - CMC_CREATE_TEST(PFX##_iter_start(), { - struct hashmultiset *set = hms_new(100, 0.6, hms_fval_numhash); - - cmc_assert_not_equals(ptr, NULL, set); - - struct hashmultiset_iter it = hms_iter_start(set); - - cmc_assert_equals(ptr, set, it.target); - cmc_assert_equals(size_t, 0, it.cursor); - cmc_assert_equals(size_t, 0, it.index); - cmc_assert_equals(size_t, 0, it.first); - cmc_assert_equals(size_t, 0, it.last); - cmc_assert_equals(bool, true, it.start); - cmc_assert_equals(bool, true, it.end); - - cmc_assert(hms_iter_at_start(&it)); - cmc_assert(hms_iter_at_end(&it)); - - cmc_assert(hms_insert(set, 1)); - cmc_assert(hms_insert(set, 2)); - cmc_assert(hms_insert(set, 3)); - - it = hms_iter_start(set); - - cmc_assert_equals(size_t, 0, it.index); - - cmc_assert_equals(size_t, 1, it.cursor); - cmc_assert_equals(size_t, 1, it.first); - cmc_assert_equals(size_t, 3, it.last); - cmc_assert_equals(bool, false, it.end); - - hms_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_end(), { - struct hashmultiset *set = hms_new(100, 0.6, hms_fval_numhash); - - cmc_assert_not_equals(ptr, NULL, set); - - struct hashmultiset_iter it = hms_iter_end(set); - - cmc_assert_equals(ptr, set, it.target); - cmc_assert_equals(size_t, 0, it.cursor); - cmc_assert_equals(size_t, 0, it.index); - cmc_assert_equals(size_t, 0, it.first); - cmc_assert_equals(size_t, 0, it.last); - cmc_assert_equals(bool, true, it.start); - cmc_assert_equals(bool, true, it.end); - - cmc_assert(hms_iter_at_start(&it)); - cmc_assert(hms_iter_at_end(&it)); - - cmc_assert(hms_insert(set, 1)); - cmc_assert(hms_insert(set, 2)); - cmc_assert(hms_insert(set, 3)); - - it = hms_iter_end(set); - - cmc_assert_equals(size_t, set->count - 1, it.index); - - cmc_assert_equals(size_t, 3, it.cursor); - cmc_assert_equals(size_t, 1, it.first); - cmc_assert_equals(size_t, 3, it.last); - cmc_assert_equals(bool, false, it.start); - - hms_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_at_start(), { - struct hashmultiset *set = hms_new(100, 0.6, hms_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - struct hashmultiset_iter it = hms_iter_start(set); - - // Empty checks - cmc_assert(hms_iter_at_start(&it)); - it = hms_iter_end(set); - cmc_assert(hms_iter_at_start(&it)); - - // Non-empty checks - cmc_assert(hms_insert(set, 1)); - cmc_assert(hms_insert(set, 2)); - it = hms_iter_end(set); - cmc_assert(!hms_iter_at_start(&it)); - it = hms_iter_start(set); - cmc_assert(hms_iter_at_start(&it)); - - hms_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_at_end(), { - struct hashmultiset *set = hms_new(100, 0.6, hms_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - struct hashmultiset_iter it = hms_iter_start(set); - - // Empty check - cmc_assert(hms_iter_at_end(&it)); - it = hms_iter_end(set); - cmc_assert(hms_iter_at_end(&it)); - - // Non-empty checks - cmc_assert(hms_insert(set, 1)); - cmc_assert(hms_insert(set, 2)); - it = hms_iter_end(set); - cmc_assert(hms_iter_at_end(&it)); - it = hms_iter_start(set); - cmc_assert(!hms_iter_at_end(&it)); - - hms_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_to_start(), { - struct hashmultiset *set = hms_new(100, 0.6, hms_fval_numhash); - - cmc_assert_not_equals(ptr, NULL, set); - - struct hashmultiset_iter it = hms_iter_start(set); - - cmc_assert(!hms_iter_to_start(&it)); - - for (size_t i = 1; i <= 100; i++) - hms_insert(set, i); - - cmc_assert_equals(size_t, 100, set->count); - - it = hms_iter_end(set); - - cmc_assert(!hms_iter_at_start(&it)); - cmc_assert(hms_iter_at_end(&it)); - - cmc_assert_equals(size_t, 100, hms_iter_value(&it)); - - cmc_assert(hms_iter_to_start(&it)); - - cmc_assert(hms_iter_at_start(&it)); - cmc_assert(!hms_iter_at_end(&it)); - - cmc_assert_equals(size_t, 1, hms_iter_value(&it)); - - hms_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_to_end(), { - struct hashmultiset *set = hms_new(100, 0.6, hms_fval_numhash); - - cmc_assert_not_equals(ptr, NULL, set); - - struct hashmultiset_iter it = hms_iter_end(set); - - cmc_assert(!hms_iter_to_end(&it)); - - for (size_t i = 1; i <= 100; i++) - hms_insert(set, i); - - it = hms_iter_start(set); - - cmc_assert(hms_iter_at_start(&it)); - cmc_assert(!hms_iter_at_end(&it)); - - cmc_assert_equals(size_t, 1, hms_iter_value(&it)); - - cmc_assert(hms_iter_to_end(&it)); - - cmc_assert(!hms_iter_at_start(&it)); - cmc_assert(hms_iter_at_end(&it)); - - cmc_assert_equals(size_t, 100, hms_iter_value(&it)); - - hms_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_next(), { - struct hashmultiset *set = hms_new(100, 0.6, hms_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - struct hashmultiset_iter it = hms_iter_start(set); - - cmc_assert(!hms_iter_next(&it)); - - for (size_t i = 1; i <= 1000; i++) - hms_insert(set, i); - - size_t sum = 0; - for (it = hms_iter_start(set); !hms_iter_at_end(&it); hms_iter_next(&it)) - { - sum += hms_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - - hms_iter_to_start(&it); - do - { - sum += hms_iter_value(&it); - } while (hms_iter_next(&it)); - - cmc_assert_equals(size_t, 500500, sum); - - hms_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_prev(), { - struct hashmultiset *set = hms_new(100, 0.6, hms_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - struct hashmultiset_iter it = hms_iter_end(set); - - cmc_assert(!hms_iter_prev(&it)); - - for (size_t i = 1; i <= 1000; i++) - hms_insert(set, i); - - size_t sum = 0; - for (it = hms_iter_end(set); !hms_iter_at_start(&it); hms_iter_prev(&it)) - { - sum += hms_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - - hms_iter_to_end(&it); - do - { - sum += hms_iter_value(&it); - } while (hms_iter_prev(&it)); - - cmc_assert_equals(size_t, 500500, sum); - - hms_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_advance(), { - struct hashmultiset *set = hms_new(100, 0.6, hms_fval_numhash); - - cmc_assert_not_equals(ptr, NULL, set); - - struct hashmultiset_iter it = hms_iter_start(set); - - cmc_assert(!hms_iter_advance(&it, 1)); - - for (size_t i = 0; i <= 1000; i++) - hms_insert(set, i); - - it = hms_iter_start(set); - - cmc_assert(!hms_iter_advance(&it, 0)); - cmc_assert(!hms_iter_advance(&it, set->count)); - - size_t sum = 0; - for (it = hms_iter_start(set);;) - { - sum += hms_iter_value(&it); - - if (!hms_iter_advance(&it, 2)) - break; - } - - cmc_assert_equals(size_t, 250500, sum); - - hms_iter_to_start(&it); - cmc_assert(hms_iter_advance(&it, set->count - 1)); - - hms_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_rewind(), { - struct hashmultiset *set = hms_new(100, 0.6, hms_fval_numhash); - - cmc_assert_not_equals(ptr, NULL, set); - - struct hashmultiset_iter it = hms_iter_end(set); - - cmc_assert(!hms_iter_rewind(&it, 1)); - - for (size_t i = 0; i <= 1000; i++) - hms_insert(set, i); - - it = hms_iter_end(set); - - cmc_assert(!hms_iter_rewind(&it, 0)); - cmc_assert(!hms_iter_rewind(&it, set->count)); - - size_t sum = 0; - for (it = hms_iter_end(set);;) - { - sum += hms_iter_value(&it); - - if (!hms_iter_rewind(&it, 2)) - break; - } - - cmc_assert_equals(size_t, 250500, sum); - - hms_iter_to_end(&it); - cmc_assert(hms_iter_rewind(&it, set->count - 1)); - - hms_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_go_to(), { - struct hashmultiset *set = hms_new(100, 0.6, hms_fval_numhash); - - cmc_assert_not_equals(ptr, NULL, set); - - struct hashmultiset_iter it = hms_iter_end(set); - cmc_assert(!hms_iter_go_to(&it, 0)); - - it = hms_iter_start(set); - cmc_assert(!hms_iter_go_to(&it, 0)); - - for (size_t i = 0; i <= 1000; i++) - hms_insert(set, i); - - it = hms_iter_start(set); - - size_t sum = 0; - for (size_t i = 0; i < 1001; i++) - { - hms_iter_go_to(&it, i); - - sum += hms_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - for (size_t i = 1001; i > 0; i--) - { - cmc_assert(hms_iter_go_to(&it, i - 1)); - - sum += hms_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - for (size_t i = 0; i < 1001; i += 100) - { - cmc_assert(hms_iter_go_to(&it, i)); - cmc_assert_equals(size_t, i, hms_iter_index(&it)); - - sum += hms_iter_value(&it); - } - - cmc_assert_equals(size_t, 5500, sum); - - hms_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_value(), { - struct hashmultiset *set = hms_new(100, 0.6, hms_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - struct hashmultiset_iter it = hms_iter_end(set); - - cmc_assert_equals(size_t, (size_t){ 0 }, hms_iter_value(&it)); - - cmc_assert(hms_insert(set, 10)); - - it = hms_iter_start(set); - - cmc_assert_equals(size_t, 10, hms_iter_value(&it)); - - hms_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_multiplicity(), { - struct hashmultiset *set = hms_new(100, 0.6, hms_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - struct hashmultiset_iter it = hms_iter_end(set); - - cmc_assert_equals(size_t, (size_t){ 0 }, hms_iter_multiplicity(&it)); - - cmc_assert(hms_insert_many(set, 10, 5)); - - it = hms_iter_start(set); - cmc_assert_equals(size_t, 5, hms_iter_multiplicity(&it)); - - it = hms_iter_end(set); - cmc_assert_equals(size_t, 5, hms_iter_multiplicity(&it)); - - hms_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_index(), { - struct hashmultiset *set = hms_new(100, 0.6, hms_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - for (size_t i = 0; i <= 1000; i++) - hms_insert(set, i); - - struct hashmultiset_iter it = hms_iter_start(set); - - for (size_t i = 0; i < 1001; i++) - { - cmc_assert_equals(size_t, i, hms_iter_index(&it)); - hms_iter_next(&it); - } - - it = hms_iter_end(set); - for (size_t i = 1001; i > 0; i--) - { - cmc_assert_equals(size_t, i - 1, hms_iter_index(&it)); - hms_iter_prev(&it); - } - - hms_free(set); - }); -}); - -#ifdef CMC_TEST_MAIN -int main(void) -{ - int result = CMCHashMultiSet() + CMCHashMultiSetIter(); - - printf(" +---------------------------------------------------------------+"); - printf("\n"); - printf(" | CMCHashMultiSet Suit : %-41s |\n", result == 0 ? "PASSED" : "FAILED"); - printf(" +---------------------------------------------------------------+"); - printf("\n\n\n"); - - return result; -} -#endif - -#endif /* CMC_TESTS_UNT_CMC_ASHMULTISET_H */ diff --git a/tests/unt/unt_cmc_hashset.h b/tests/unt/unt_cmc_hashset.h deleted file mode 100644 index 2607bf9..0000000 --- a/tests/unt/unt_cmc_hashset.h +++ /dev/null @@ -1,1044 +0,0 @@ -#ifndef CMC_TESTS_UNT_CMC_ASHSET_H -#define CMC_TESTS_UNT_CMC_ASHSET_H - -#include "utl.h" - -#include "tst_cmc_hashset.h" - -struct hashset_fval *hs_fval = &(struct hashset_fval){ - .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp -}; - -struct hashset_fval *hs_fval_counter = &(struct hashset_fval){ - .cmp = v_c_cmp, .cpy = v_c_cpy, .str = v_c_str, .free = v_c_free, .hash = v_c_hash, .pri = v_c_pri -}; - -struct cmc_alloc_node *hs_alloc_node = - &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free }; - -CMC_CREATE_UNIT(CMCHashSet, true, { - CMC_CREATE_TEST(PFX##_new(), { - struct hashset *set = hs_new(943722, 0.6, hs_fval); - - cmc_assert_not_equals(ptr, NULL, set); - cmc_assert_not_equals(ptr, NULL, set->buffer); - cmc_assert_equals(size_t, 0, set->count); - cmc_assert_equals(double, 0.6, set->load); - cmc_assert_equals(int32_t, CMC_FLAG_OK, set->flag); - cmc_assert_equals(ptr, hs_fval, set->f_val); - cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, set->alloc->malloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, set->alloc->calloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, set->alloc->realloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.free, set->alloc->free); - cmc_assert_equals(ptr, NULL, set->callbacks); - - cmc_assert_greater_equals(size_t, (943722 / 0.6), hs_capacity(set)); - - hs_free(set); - - set = hs_new(0, 0.6, hs_fval); - cmc_assert_equals(ptr, NULL, set); - - set = hs_new(UINT64_MAX, 0.99, hs_fval); - cmc_assert_equals(ptr, NULL, set); - - set = hs_new(1000, 0.6, NULL); - cmc_assert_equals(ptr, NULL, set); - - set = hs_new(1000, 0.6, NULL); - cmc_assert_equals(ptr, NULL, set); - }); - - CMC_CREATE_TEST(PFX##_new_custom(), { - struct hashset *set = hs_new_custom(943722, 0.6, hs_fval, hs_alloc_node, callbacks); - - cmc_assert_not_equals(ptr, NULL, set); - cmc_assert_not_equals(ptr, NULL, set->buffer); - cmc_assert_equals(size_t, 0, set->count); - cmc_assert_equals(double, 0.6, set->load); - cmc_assert_equals(int32_t, CMC_FLAG_OK, set->flag); - cmc_assert_equals(ptr, hs_fval, set->f_val); - cmc_assert_equals(ptr, hs_alloc_node, set->alloc); - cmc_assert_equals(ptr, callbacks, set->callbacks); - - cmc_assert_greater_equals(size_t, (943722 / 0.6), hs_capacity(set)); - - hs_free(set); - - set = hs_new_custom(0, 0.6, hs_fval, NULL, NULL); - cmc_assert_equals(ptr, NULL, set); - - set = hs_new_custom(UINT64_MAX, 0.99, hs_fval, NULL, NULL); - cmc_assert_equals(ptr, NULL, set); - - set = hs_new_custom(1000, 0.6, NULL, NULL, NULL); - cmc_assert_equals(ptr, NULL, set); - }); - - CMC_CREATE_TEST(PFX##_clear(), { - v_total_free = 0; - struct hashset *set = hs_new(100, 0.6, hs_fval_counter); - - cmc_assert_not_equals(ptr, NULL, set); - - for (size_t i = 1; i <= 1000; i++) - hs_insert(set, i); - - cmc_assert_equals(size_t, 1000, set->count); - - set->flag = CMC_FLAG_ERROR; - hs_clear(set); - - cmc_assert_equals(size_t, 0, set->count); - cmc_assert_equals(int32_t, CMC_FLAG_OK, set->flag); - cmc_assert_equals(int32_t, 1000, v_total_free); - - hs_free(set); - v_total_free = 0; - }); - - CMC_CREATE_TEST(PFX##_free(), { - v_total_free = 0; - struct hashset *set = hs_new(100, 0.6, hs_fval_counter); - - cmc_assert_not_equals(ptr, NULL, set); - - for (size_t i = 1; i <= 1000; i++) - hs_insert(set, i); - - cmc_assert_equals(size_t, 1000, set->count); - - hs_free(set); - - cmc_assert_equals(int32_t, 1000, v_total_free); - - set = hs_new(1000, 0.6, hs_fval_counter); - - cmc_assert_not_equals(ptr, NULL, set); - cmc_assert_not_equals(ptr, NULL, set->buffer); - - hs_free(set); - - cmc_assert_equals(int32_t, 1000, v_total_free); - v_total_free = 0; - }); - - CMC_CREATE_TEST(insert, { - struct hashset *set = hs_new(100, 0.6, hs_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - cmc_assert(hs_insert(set, 1)); - cmc_assert_equals(size_t, 1, hs_count(set)); - - hs_free(set); - }); - - CMC_CREATE_TEST(insert[smallest capacity], { - struct hashset *set = hs_new(1, 0.99, hs_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - cmc_assert_equals(size_t, cmc_hashtable_primes[0], hs_capacity(set)); - cmc_assert(hs_insert(set, 1)); - - hs_free(set); - }); - - CMC_CREATE_TEST(insert[element position], { - struct hashset *set = hs_new(1, 0.99, hs_fval); - - // Temporary change - // Using the numhash the key is the hash itself - hs_fval->hash = numhash; - - cmc_assert_not_equals(ptr, NULL, set); - - size_t capacity = hs_capacity(set); - - cmc_assert_greater(size_t, 0, capacity); - - cmc_assert(hs_insert(set, capacity - 1)); - cmc_assert(hs_insert(set, capacity)); - - cmc_assert_equals(size_t, capacity - 1, set->buffer[capacity - 1].value); - cmc_assert_equals(size_t, capacity, set->buffer[0].value); - - hs_fval->hash = cmc_size_hash; - - hs_free(set); - }); - - CMC_CREATE_TEST(insert[distance], { - struct hashset *set = hs_new(500, 0.6, hs_fval); - - // Temporary change - hs_fval->hash = hash0; - - cmc_assert_not_equals(ptr, NULL, set); - - for (size_t i = 0; i < 200; i++) - cmc_assert(hs_insert(set, i)); - - // Everything is hashed to 0 so key 0 should have dist 0, key 1 dist 1, - // etc - for (size_t i = 0; i < 200; i++) - cmc_assert_equals(size_t, i, set->buffer[i].dist); - - hs_fval->hash = cmc_size_hash; - - hs_free(set); - }); - - CMC_CREATE_TEST(insert[distance wrap], { - struct hashset *set = hs_new(1, 0.99, hs_fval); - - // Temporary change - hs_fval->hash = hashcapminus1; - - cmc_assert_not_equals(ptr, NULL, set); - - size_t capacity = hs_capacity(set); - - // Just to be sure, not part of the test - cmc_assert_equals(size_t, cmc_hashtable_primes[0] - 1, hashcapminus1(0)); - cmc_assert_equals(size_t, capacity - 1, hashcapminus1(0)); - - cmc_assert(hs_insert(set, 0)); - cmc_assert(hs_insert(set, 1)); - - cmc_assert_equals(size_t, 0, set->buffer[capacity - 1].dist); - cmc_assert_equals(size_t, 1, set->buffer[0].dist); - - hs_fval->hash = cmc_size_hash; - - hs_free(set); - }); - - CMC_CREATE_TEST(insert[distances], { - struct hashset *set = hs_new(1, 0.99, hs_fval); - - // Temporary change - hs_fval->hash = hashcapminus4; - - cmc_assert_not_equals(ptr, NULL, set); - - cmc_assert_equals(size_t, cmc_hashtable_primes[0], hs_capacity(set)); - - for (size_t i = 0; i < 6; i++) - cmc_assert(hs_insert(set, i)); - - // for (size_t i = 0; i < 6; i++) - // cmc_assert_equals(size_t, i, hs_impl_get_entry(set, i)->dist); - - hs_fval->hash = cmc_size_hash; - - hs_free(set); - }); - - CMC_CREATE_TEST(insert[buffer growth and item preservation], { - struct hashset *set = hs_new(1, 0.99, hs_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - cmc_assert_equals(size_t, cmc_hashtable_primes[0], hs_capacity(set)); - - size_t p = 0; - for (size_t i = 0; i < 100000; i++) - { - if (hs_full(set)) - p++; - - cmc_assert(hs_insert(set, i)); - } - - cmc_assert_equals(size_t, cmc_hashtable_primes[p], hs_capacity(set)); - - for (size_t i = 0; i < 100000; i++) - cmc_assert(hs_contains(set, i)); - - hs_free(set); - }); - - CMC_CREATE_TEST(remove, { - struct hashset *set = hs_new(100, 0.6, hs_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - for (size_t i = 0; i < 100; i++) - cmc_assert(hs_insert(set, i)); - - for (size_t i = 0; i < 100; i++) - cmc_assert(hs_remove(set, i)); - - hs_free(set); - }); - - CMC_CREATE_TEST(remove[count = 0], { - struct hashset *set = hs_new(100, 0.6, hs_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - for (size_t i = 100; i < 200; i++) - cmc_assert(!hs_remove(set, i)); - - hs_free(set); - }); - - CMC_CREATE_TEST(remove[key not found], { - struct hashset *set = hs_new(100, 0.6, hs_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - for (size_t i = 0; i < 100; i++) - cmc_assert(hs_insert(set, i)); - - for (size_t i = 100; i < 200; i++) - cmc_assert(!hs_remove(set, i)); - - hs_free(set); - }); - - CMC_CREATE_TEST(max, { - struct hashset *set = hs_new(100, 0.6, hs_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - for (size_t i = 1; i <= 100; i++) - cmc_assert(hs_insert(set, i)); - - size_t val; - cmc_assert(hs_max(set, &val)); - - cmc_assert_equals(size_t, 100, val); - - hs_free(set); - }); - - CMC_CREATE_TEST(max[count = 0], { - struct hashset *set = hs_new(100, 0.6, hs_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - cmc_assert(!hs_min(set, NULL)); - - hs_free(set); - }); - - CMC_CREATE_TEST(min, { - struct hashset *set = hs_new(100, 0.6, hs_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - for (size_t i = 1; i <= 100; i++) - cmc_assert(hs_insert(set, i)); - - size_t val; - cmc_assert(hs_min(set, &val)); - - cmc_assert_equals(size_t, 1, val); - - hs_free(set); - }); - - CMC_CREATE_TEST(min[count = 0], { - struct hashset *set = hs_new(100, 0.6, hs_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - cmc_assert(!hs_min(set, NULL)); - - hs_free(set); - }); - - CMC_CREATE_TEST(contains, { - struct hashset *set = hs_new(100, 0.6, hs_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - cmc_assert(hs_insert(set, 987654321)); - - cmc_assert(hs_contains(set, 987654321)); - - hs_free(set); - }); - - CMC_CREATE_TEST(contains[count = 0], { - struct hashset *set = hs_new(100, 0.6, hs_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - cmc_assert(!hs_contains(set, 987654321)); - - hs_free(set); - }); - - CMC_CREATE_TEST(contains[sum], { - struct hashset *set = hs_new(100, 0.6, hs_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - for (size_t i = 101; i <= 200; i++) - cmc_assert(hs_insert(set, i)); - - size_t sum = 0; - for (size_t i = 1; i <= 300; i++) - if (hs_contains(set, i)) - sum += i; - - cmc_assert_equals(size_t, 15050, sum); - - hs_free(set); - }); - - CMC_CREATE_TEST(empty, { - struct hashset *set = hs_new(100, 0.6, hs_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - cmc_assert(hs_empty(set)); - - cmc_assert(hs_insert(set, 1)); - - cmc_assert(!hs_empty(set)); - - hs_free(set); - }); - - CMC_CREATE_TEST(full, { - struct hashset *set = hs_new(cmc_hashtable_primes[0], 0.99999, hs_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - cmc_assert_equals(size_t, cmc_hashtable_primes[0], hs_capacity(set)); - - for (size_t i = 0; i < hs_capacity(set); i++) - cmc_assert(hs_insert(set, i)); - - cmc_assert(hs_full(set)); - - cmc_assert(hs_insert(set, 10000)); - - cmc_assert_equals(size_t, cmc_hashtable_primes[1], hs_capacity(set)); - - cmc_assert(!hs_full(set)); - - hs_free(set); - }); - - CMC_CREATE_TEST(count, { - struct hashset *set = hs_new(100, 0.6, hs_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - for (size_t i = 1; i < 100; i++) - { - cmc_assert(hs_insert(set, i)); - cmc_assert_equals(size_t, i, hs_count(set)); - } - - hs_free(set); - }); - - CMC_CREATE_TEST(capacity, { - struct hashset *set = hs_new(2500, 0.6, hs_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - cmc_assert_greater_equals(size_t, (size_t)(2500 / 0.6), hs_capacity(set)); - - hs_free(set); - }); - - CMC_CREATE_TEST(capacity[small], { - struct hashset *set = hs_new(1, 0.99, hs_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - cmc_assert_equals(size_t, cmc_hashtable_primes[0], hs_capacity(set)); - - hs_free(set); - }); - - CMC_CREATE_TEST(load, { - struct hashset *set = hs_new(1, 0.99, hs_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - cmc_assert_in_range(double, 0.99 - 0.0001, 0.99 + 0.0001, hs_load(set)); - - hs_free(set); - }); - - CMC_CREATE_TEST(flags, { - struct hashset *set = hs_new(1, 0.99, hs_fval); - - cmc_assert_not_equals(ptr, NULL, set); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hs_flag(set)); - - // insert - cmc_assert(hs_insert(set, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hs_flag(set)); - cmc_assert(!hs_insert(set, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hs_flag(set)); - - // clear - hs_clear(set); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hs_flag(set)); - - cmc_assert(hs_insert(set, 1)); - - // remove - cmc_assert(!hs_remove(set, 2)); - cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hs_flag(set)); - - cmc_assert(hs_remove(set, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hs_flag(set)); - - cmc_assert(!hs_remove(set, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hs_flag(set)); - - // max - cmc_assert(hs_insert(set, 1)); - cmc_assert(hs_max(set, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hs_flag(set)); - - cmc_assert(hs_remove(set, 1)); - cmc_assert(!hs_max(set, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hs_flag(set)); - - // min - cmc_assert(hs_insert(set, 1)); - cmc_assert(hs_min(set, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hs_flag(set)); - - cmc_assert(hs_remove(set, 1)); - cmc_assert(!hs_min(set, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hs_flag(set)); - - // contains - hs_contains(set, 1); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hs_flag(set)); - - // copy - set->flag = CMC_FLAG_ERROR; - struct hashset *set2 = hs_copy_of(set); - - cmc_assert_equals(int32_t, CMC_FLAG_OK, hs_flag(set)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hs_flag(set2)); - - size_t tmp = set->capacity; - set->capacity = 0; - - struct hashset *set3 = hs_copy_of(set); - cmc_assert_equals(ptr, NULL, set3); - - cmc_assert_equals(int32_t, CMC_FLAG_ERROR, hs_flag(set)); - - set->capacity = tmp; - - cmc_assert(hs_equals(set, set2)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hs_flag(set)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, hs_flag(set2)); - - hs_free(set); - hs_free(set2); - }); - - CMC_CREATE_TEST(callbacks, { - struct hashset *set = hs_new_custom(100, 0.6, hs_fval, NULL, callbacks); - - cmc_assert_not_equals(ptr, NULL, set); - - total_create = 0; - total_read = 0; - total_update = 0; - total_delete = 0; - total_resize = 0; - - cmc_assert(hs_insert(set, 1)); - cmc_assert_equals(int32_t, 1, total_create); - - cmc_assert(hs_remove(set, 1)); - cmc_assert_equals(int32_t, 1, total_delete); - - cmc_assert(hs_insert(set, 1)); - cmc_assert_equals(int32_t, 2, total_create); - - cmc_assert(hs_max(set, NULL)); - cmc_assert_equals(int32_t, 1, total_read); - - cmc_assert(hs_min(set, NULL)); - cmc_assert_equals(int32_t, 2, total_read); - - cmc_assert(hs_contains(set, 1)); - cmc_assert_equals(int32_t, 3, total_read); - - cmc_assert(hs_resize(set, 10000)); - cmc_assert_equals(int32_t, 1, total_resize); - - cmc_assert(hs_resize(set, 500)); - cmc_assert_equals(int32_t, 2, total_resize); - - cmc_assert_equals(int32_t, 2, total_create); - cmc_assert_equals(int32_t, 3, total_read); - cmc_assert_equals(int32_t, 0, total_update); - cmc_assert_equals(int32_t, 1, total_delete); - cmc_assert_equals(int32_t, 2, total_resize); - - hs_customize(set, NULL, NULL); - - cmc_assert_equals(ptr, NULL, set->callbacks); - - hs_clear(set); - cmc_assert(hs_resize(set, 10000)); - cmc_assert(hs_resize(set, 500)); - cmc_assert(hs_insert(set, 1)); - cmc_assert(hs_remove(set, 1)); - cmc_assert(hs_insert(set, 1)); - cmc_assert(hs_max(set, NULL)); - cmc_assert(hs_min(set, NULL)); - cmc_assert(hs_contains(set, 1)); - - cmc_assert_equals(int32_t, 2, total_create); - cmc_assert_equals(int32_t, 3, total_read); - cmc_assert_equals(int32_t, 0, total_update); - cmc_assert_equals(int32_t, 1, total_delete); - cmc_assert_equals(int32_t, 2, total_resize); - - cmc_assert_equals(ptr, NULL, set->callbacks); - - hs_free(set); - - total_create = 0; - total_read = 0; - total_update = 0; - total_delete = 0; - total_resize = 0; - }); -}); - -struct hashset_fval *hs_fval_numhash = &(struct hashset_fval){ - .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = numhash, .pri = cmc_size_cmp -}; - -CMC_CREATE_UNIT(CMCHashSetIter, true, { - CMC_CREATE_TEST(PFX##_iter_start(), { - struct hashset *set = hs_new(100, 0.6, hs_fval_numhash); - - cmc_assert_not_equals(ptr, NULL, set); - - struct hashset_iter it = hs_iter_start(set); - - cmc_assert_equals(ptr, set, it.target); - cmc_assert_equals(size_t, 0, it.cursor); - cmc_assert_equals(size_t, 0, it.index); - cmc_assert_equals(size_t, 0, it.first); - cmc_assert_equals(size_t, 0, it.last); - cmc_assert_equals(bool, true, it.start); - cmc_assert_equals(bool, true, it.end); - - cmc_assert(hs_iter_at_start(&it)); - cmc_assert(hs_iter_at_end(&it)); - - cmc_assert(hs_insert(set, 1)); - cmc_assert(hs_insert(set, 2)); - cmc_assert(hs_insert(set, 3)); - - it = hs_iter_start(set); - - cmc_assert_equals(size_t, 0, it.index); - - cmc_assert_equals(size_t, 1, it.cursor); - cmc_assert_equals(size_t, 1, it.first); - cmc_assert_equals(size_t, 3, it.last); - cmc_assert_equals(bool, false, it.end); - - hs_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_end(), { - struct hashset *set = hs_new(100, 0.6, hs_fval_numhash); - - cmc_assert_not_equals(ptr, NULL, set); - - struct hashset_iter it = hs_iter_end(set); - - cmc_assert_equals(ptr, set, it.target); - cmc_assert_equals(size_t, 0, it.cursor); - cmc_assert_equals(size_t, 0, it.index); - cmc_assert_equals(size_t, 0, it.first); - cmc_assert_equals(size_t, 0, it.last); - cmc_assert_equals(bool, true, it.start); - cmc_assert_equals(bool, true, it.end); - - cmc_assert(hs_iter_at_start(&it)); - cmc_assert(hs_iter_at_end(&it)); - - cmc_assert(hs_insert(set, 1)); - cmc_assert(hs_insert(set, 2)); - cmc_assert(hs_insert(set, 3)); - - it = hs_iter_end(set); - - cmc_assert_equals(size_t, set->count - 1, it.index); - - cmc_assert_equals(size_t, 3, it.cursor); - cmc_assert_equals(size_t, 1, it.first); - cmc_assert_equals(size_t, 3, it.last); - cmc_assert_equals(bool, false, it.start); - - hs_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_at_start(), { - struct hashset *set = hs_new(100, 0.6, hs_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - struct hashset_iter it = hs_iter_start(set); - - // Empty checks - cmc_assert(hs_iter_at_start(&it)); - it = hs_iter_end(set); - cmc_assert(hs_iter_at_start(&it)); - - // Non-empty checks - cmc_assert(hs_insert(set, 1)); - cmc_assert(hs_insert(set, 2)); - it = hs_iter_end(set); - cmc_assert(!hs_iter_at_start(&it)); - it = hs_iter_start(set); - cmc_assert(hs_iter_at_start(&it)); - - hs_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_at_end(), { - struct hashset *set = hs_new(100, 0.6, hs_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - struct hashset_iter it = hs_iter_start(set); - - // Empty check - cmc_assert(hs_iter_at_end(&it)); - it = hs_iter_end(set); - cmc_assert(hs_iter_at_end(&it)); - - // Non-empty checks - cmc_assert(hs_insert(set, 1)); - cmc_assert(hs_insert(set, 2)); - it = hs_iter_end(set); - cmc_assert(hs_iter_at_end(&it)); - it = hs_iter_start(set); - cmc_assert(!hs_iter_at_end(&it)); - - hs_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_to_start(), { - struct hashset *set = hs_new(100, 0.6, hs_fval_numhash); - - cmc_assert_not_equals(ptr, NULL, set); - - struct hashset_iter it = hs_iter_start(set); - - cmc_assert(!hs_iter_to_start(&it)); - - for (size_t i = 1; i <= 100; i++) - hs_insert(set, i); - - cmc_assert_equals(size_t, 100, set->count); - - it = hs_iter_end(set); - - cmc_assert(!hs_iter_at_start(&it)); - cmc_assert(hs_iter_at_end(&it)); - - cmc_assert_equals(size_t, 100, hs_iter_value(&it)); - - cmc_assert(hs_iter_to_start(&it)); - - cmc_assert(hs_iter_at_start(&it)); - cmc_assert(!hs_iter_at_end(&it)); - - cmc_assert_equals(size_t, 1, hs_iter_value(&it)); - - hs_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_to_end(), { - struct hashset *set = hs_new(100, 0.6, hs_fval_numhash); - - cmc_assert_not_equals(ptr, NULL, set); - - struct hashset_iter it = hs_iter_end(set); - - cmc_assert(!hs_iter_to_end(&it)); - - for (size_t i = 1; i <= 100; i++) - hs_insert(set, i); - - it = hs_iter_start(set); - - cmc_assert(hs_iter_at_start(&it)); - cmc_assert(!hs_iter_at_end(&it)); - - cmc_assert_equals(size_t, 1, hs_iter_value(&it)); - - cmc_assert(hs_iter_to_end(&it)); - - cmc_assert(!hs_iter_at_start(&it)); - cmc_assert(hs_iter_at_end(&it)); - - cmc_assert_equals(size_t, 100, hs_iter_value(&it)); - - hs_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_next(), { - struct hashset *set = hs_new(100, 0.6, hs_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - struct hashset_iter it = hs_iter_start(set); - - cmc_assert(!hs_iter_next(&it)); - - for (size_t i = 1; i <= 1000; i++) - hs_insert(set, i); - - size_t sum = 0; - for (it = hs_iter_start(set); !hs_iter_at_end(&it); hs_iter_next(&it)) - { - sum += hs_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - - hs_iter_to_start(&it); - do - { - sum += hs_iter_value(&it); - } while (hs_iter_next(&it)); - - cmc_assert_equals(size_t, 500500, sum); - - hs_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_prev(), { - struct hashset *set = hs_new(100, 0.6, hs_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - struct hashset_iter it = hs_iter_end(set); - - cmc_assert(!hs_iter_prev(&it)); - - for (size_t i = 1; i <= 1000; i++) - hs_insert(set, i); - - size_t sum = 0; - for (it = hs_iter_end(set); !hs_iter_at_start(&it); hs_iter_prev(&it)) - { - sum += hs_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - - hs_iter_to_end(&it); - do - { - sum += hs_iter_value(&it); - } while (hs_iter_prev(&it)); - - cmc_assert_equals(size_t, 500500, sum); - - hs_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_advance(), { - struct hashset *set = hs_new(100, 0.6, hs_fval_numhash); - - cmc_assert_not_equals(ptr, NULL, set); - - struct hashset_iter it = hs_iter_start(set); - - cmc_assert(!hs_iter_advance(&it, 1)); - - for (size_t i = 0; i <= 1000; i++) - hs_insert(set, i); - - it = hs_iter_start(set); - - cmc_assert(!hs_iter_advance(&it, 0)); - cmc_assert(!hs_iter_advance(&it, set->count)); - - size_t sum = 0; - for (it = hs_iter_start(set);;) - { - sum += hs_iter_value(&it); - - if (!hs_iter_advance(&it, 2)) - break; - } - - cmc_assert_equals(size_t, 250500, sum); - - hs_iter_to_start(&it); - cmc_assert(hs_iter_advance(&it, set->count - 1)); - - hs_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_rewind(), { - struct hashset *set = hs_new(100, 0.6, hs_fval_numhash); - - cmc_assert_not_equals(ptr, NULL, set); - - struct hashset_iter it = hs_iter_end(set); - - cmc_assert(!hs_iter_rewind(&it, 1)); - - for (size_t i = 0; i <= 1000; i++) - hs_insert(set, i); - - it = hs_iter_end(set); - - cmc_assert(!hs_iter_rewind(&it, 0)); - cmc_assert(!hs_iter_rewind(&it, set->count)); - - size_t sum = 0; - for (it = hs_iter_end(set);;) - { - sum += hs_iter_value(&it); - - if (!hs_iter_rewind(&it, 2)) - break; - } - - cmc_assert_equals(size_t, 250500, sum); - - hs_iter_to_end(&it); - cmc_assert(hs_iter_rewind(&it, set->count - 1)); - - hs_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_go_to(), { - struct hashset *set = hs_new(100, 0.6, hs_fval_numhash); - - cmc_assert_not_equals(ptr, NULL, set); - - struct hashset_iter it = hs_iter_end(set); - cmc_assert(!hs_iter_go_to(&it, 0)); - - it = hs_iter_start(set); - cmc_assert(!hs_iter_go_to(&it, 0)); - - for (size_t i = 0; i <= 1000; i++) - hs_insert(set, i); - - it = hs_iter_start(set); - - size_t sum = 0; - for (size_t i = 0; i < 1001; i++) - { - hs_iter_go_to(&it, i); - - sum += hs_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - for (size_t i = 1001; i > 0; i--) - { - cmc_assert(hs_iter_go_to(&it, i - 1)); - - sum += hs_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - for (size_t i = 0; i < 1001; i += 100) - { - cmc_assert(hs_iter_go_to(&it, i)); - cmc_assert_equals(size_t, i, hs_iter_index(&it)); - - sum += hs_iter_value(&it); - } - - cmc_assert_equals(size_t, 5500, sum); - - hs_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_value(), { - struct hashset *set = hs_new(100, 0.6, hs_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - struct hashset_iter it = hs_iter_end(set); - - cmc_assert_equals(size_t, (size_t){ 0 }, hs_iter_value(&it)); - - cmc_assert(hs_insert(set, 10)); - - it = hs_iter_start(set); - - cmc_assert_equals(size_t, 10, hs_iter_value(&it)); - - hs_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_index(), { - struct hashset *set = hs_new(100, 0.6, hs_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - for (size_t i = 0; i <= 1000; i++) - hs_insert(set, i); - - struct hashset_iter it = hs_iter_start(set); - - for (size_t i = 0; i < 1001; i++) - { - cmc_assert_equals(size_t, i, hs_iter_index(&it)); - hs_iter_next(&it); - } - - it = hs_iter_end(set); - for (size_t i = 1001; i > 0; i--) - { - cmc_assert_equals(size_t, i - 1, hs_iter_index(&it)); - hs_iter_prev(&it); - } - - hs_free(set); - }); -}); - -#ifdef CMC_TEST_MAIN -int main(void) -{ - int result = CMCHashSet() + CMCHashSetIter(); - - printf(" +---------------------------------------------------------------+"); - printf("\n"); - printf(" | CMCHashSet Suit : %-46s |\n", result == 0 ? "PASSED" : "FAILED"); - printf(" +---------------------------------------------------------------+"); - printf("\n\n\n"); - - return result; -} -#endif - -#endif /* CMC_TESTS_UNT_CMC_ASHSET_H */ diff --git a/tests/unt/unt_cmc_heap.h b/tests/unt/unt_cmc_heap.h deleted file mode 100644 index 77bf4ed..0000000 --- a/tests/unt/unt_cmc_heap.h +++ /dev/null @@ -1,729 +0,0 @@ -#ifndef CMC_TESTS_UNT_CMC_EAP_H -#define CMC_TESTS_UNT_CMC_EAP_H - -#include "utl.h" - -#include "tst_cmc_heap.h" - -struct heap_fval *h_fval = &(struct heap_fval){ - .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp -}; - -CMC_CREATE_UNIT(CMCHeap, true, { - CMC_CREATE_TEST(new, { - struct heap *h = h_new(1000000, CMC_MAX_HEAP, h_fval); - - cmc_assert_not_equals(ptr, NULL, h); - cmc_assert_not_equals(ptr, NULL, h->buffer); - cmc_assert_equals(size_t, 1000000, h_capacity(h)); - cmc_assert_equals(size_t, 0, h_count(h)); - - h_free(h); - }); - - CMC_CREATE_TEST(new[edge_case capacity = 0], { - struct heap *h = h_new(0, CMC_MAX_HEAP, h_fval); - - cmc_assert_equals(ptr, NULL, h); - }); - - CMC_CREATE_TEST(new[edge_case capacity = UINT64_MAX], { - struct heap *h = h_new(UINT64_MAX, CMC_MAX_HEAP, h_fval); - - cmc_assert_equals(ptr, NULL, h); - }); - - CMC_CREATE_TEST(clear[count capacity], { - struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); - - cmc_assert_not_equals(ptr, NULL, h); - - for (size_t i = 0; i < 50; i++) - h_insert(h, i); - - cmc_assert_equals(size_t, 50, h_count(h)); - - h_clear(h); - - cmc_assert_equals(size_t, 0, h_count(h)); - cmc_assert_equals(size_t, 100, h_capacity(h)); - - h_free(h); - }); - - CMC_CREATE_TEST(buffer_growth[edge_case capacity = 1], { - struct heap *h = h_new(1, CMC_MAX_HEAP, h_fval); - - cmc_assert_not_equals(ptr, NULL, h); - - for (size_t i = 0; i < 50; i++) - cmc_assert(h_insert(h, i)); - - cmc_assert_equals(size_t, 50, h_count(h)); - - h_free(h); - }); - - CMC_CREATE_TEST(insert, { - struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); - - cmc_assert_not_equals(ptr, NULL, h); - - cmc_assert(h_insert(h, 10)); - - h_free(h); - }); - - CMC_CREATE_TEST(insert[item preservation], { - struct heap *h = h_new(50, CMC_MAX_HEAP, h_fval); - - cmc_assert_not_equals(ptr, NULL, h); - - for (size_t i = 0; i <= 100; i++) - cmc_assert(h_insert(h, i)); - - size_t sum = 0; - for (size_t i = 0; i < h_count(h); i++) - sum += h->buffer[i]; - - cmc_assert_equals(size_t, 5050, sum); - - h_free(h); - }); - - CMC_CREATE_TEST(remove, { - struct heap *h = h_new(50, CMC_MAX_HEAP, h_fval); - - cmc_assert_not_equals(ptr, NULL, h); - - for (size_t i = 0; i <= 100; i++) - cmc_assert(h_insert(h, i)); - - cmc_assert_equals(size_t, 100, h_peek(h)); - cmc_assert(h_remove(h)); - cmc_assert_equals(size_t, 99, h_peek(h)); - - h_free(h); - }); - - CMC_CREATE_TEST(remove[count = 0], { - struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); - - cmc_assert_not_equals(ptr, NULL, h); - - cmc_assert(!h_remove(h)); - - h_free(h); - }); - - CMC_CREATE_TEST(remove[sorted], { - struct heap *h = h_new(100, CMC_MIN_HEAP, h_fval); - - cmc_assert_not_equals(ptr, NULL, h); - - for (size_t i = 1; i <= 100; i++) - cmc_assert(h_insert(h, i)); - - size_t i = 0; - size_t arr[100]; - while (!h_empty(h)) - { - arr[i++] = h_peek(h); - cmc_assert(h_remove(h)); - } - - cmc_assert_array_sorted_any(size_t, arr, cmc_size_cmp, 0, 99); - - h_free(h); - }); - - CMC_CREATE_TEST(peek, { - struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); - - cmc_assert_not_equals(ptr, NULL, h); - - for (size_t i = 1; i <= 100; i++) - cmc_assert(h_insert(h, i)); - - cmc_assert_equals(size_t, 100, h_peek(h)); - - h_free(h); - }); - - CMC_CREATE_TEST(peek[count = 0], { - struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); - - cmc_assert_not_equals(ptr, NULL, h); - - cmc_assert_equals(size_t, (size_t){ 0 }, h_peek(h)); - - h_free(h); - }); - - CMC_CREATE_TEST(flags, { - struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); - - cmc_assert_not_equals(ptr, NULL, h); - cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h)); - - h->flag = CMC_FLAG_ERROR; - - // insert - cmc_assert(h_insert(h, 10)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h)); - - h->flag = CMC_FLAG_ERROR; - - // remove - cmc_assert(h_remove(h)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h)); - - cmc_assert(!h_remove(h)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, h_flag(h)); - - // peek - cmc_assert(h_insert(h, 10)); - h_peek(h); - cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h)); - cmc_assert(h_remove(h)); - h_peek(h); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, h_flag(h)); - - // clear - h_clear(h); - cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h)); - - h->flag = CMC_FLAG_ERROR; - - // contains - h_contains(h, 10); - cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h)); - - h->flag = CMC_FLAG_ERROR; - - // copy of - struct heap *h2 = h_copy_of(h); - cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h2)); - - h->flag = CMC_FLAG_ERROR; - h2->flag = CMC_FLAG_ERROR; - - // equals - cmc_assert(h_equals(h, h2)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h2)); - - h_free(h); - h_free(h2); - }); - - CMC_CREATE_TEST(callbacks, { - struct heap *h = h_new_custom(100, CMC_MAX_HEAP, h_fval, NULL, callbacks); - - cmc_assert_not_equals(ptr, NULL, h); - - total_create = 0; - total_read = 0; - total_update = 0; - total_delete = 0; - total_resize = 0; - - cmc_assert(h_insert(h, 10)); - cmc_assert_equals(int32_t, 1, total_create); - - cmc_assert(h_remove(h)); - cmc_assert_equals(int32_t, 1, total_delete); - - cmc_assert(h_insert(h, 10)); - cmc_assert_equals(int32_t, 2, total_create); - - cmc_assert_equals(size_t, 10, h_peek(h)); - cmc_assert_equals(int32_t, 1, total_read); - - cmc_assert(h_contains(h, 10)); - cmc_assert_equals(int32_t, 2, total_read); - - cmc_assert(h_resize(h, 1000)); - cmc_assert_equals(int32_t, 1, total_resize); - - cmc_assert(h_resize(h, 100)); - cmc_assert_equals(int32_t, 2, total_resize); - - cmc_assert_equals(int32_t, 2, total_create); - cmc_assert_equals(int32_t, 2, total_read); - cmc_assert_equals(int32_t, 0, total_update); - cmc_assert_equals(int32_t, 1, total_delete); - cmc_assert_equals(int32_t, 2, total_resize); - - h_customize(h, NULL, NULL); - - cmc_assert_equals(ptr, NULL, h->callbacks); - - h_clear(h); - cmc_assert(h_insert(h, 10)); - cmc_assert(h_remove(h)); - cmc_assert(h_insert(h, 10)); - cmc_assert_equals(size_t, 10, h_peek(h)); - cmc_assert(h_contains(h, 10)); - cmc_assert(h_resize(h, 1000)); - cmc_assert(h_resize(h, 100)); - - cmc_assert_equals(int32_t, 2, total_create); - cmc_assert_equals(int32_t, 2, total_read); - cmc_assert_equals(int32_t, 0, total_update); - cmc_assert_equals(int32_t, 1, total_delete); - cmc_assert_equals(int32_t, 2, total_resize); - - cmc_assert_equals(ptr, NULL, h->callbacks); - - h_free(h); - - total_create = 0; - total_read = 0; - total_update = 0; - total_delete = 0; - total_resize = 0; - }); -}); - -CMC_CREATE_UNIT(CMCHeapIter, true, { - CMC_CREATE_TEST(PFX##_iter_start(), { - struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); - - cmc_assert_not_equals(ptr, NULL, h); - - struct heap_iter it = h_iter_start(h); - - cmc_assert_equals(ptr, h, it.target); - cmc_assert_equals(size_t, 0, it.cursor); - cmc_assert_equals(bool, true, it.start); - cmc_assert_equals(bool, true, it.end); - - cmc_assert(h_iter_at_start(&it)); - cmc_assert(h_iter_at_end(&it)); - - cmc_assert(h_insert(h, 1)); - cmc_assert(h_insert(h, 2)); - - it = h_iter_start(h); - - cmc_assert_equals(size_t, 0, it.cursor); - cmc_assert_equals(bool, false, it.end); - - h_free(h); - }); - - CMC_CREATE_TEST(PFX##_iter_end(), { - struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); - - cmc_assert_not_equals(ptr, NULL, h); - - struct heap_iter it = h_iter_end(h); - - cmc_assert_equals(ptr, h, it.target); - cmc_assert_equals(size_t, 0, it.cursor); - cmc_assert_equals(bool, true, it.start); - cmc_assert_equals(bool, true, it.end); - - cmc_assert(h_iter_at_start(&it)); - cmc_assert(h_iter_at_end(&it)); - - cmc_assert(h_insert(h, 1)); - cmc_assert(h_insert(h, 2)); - cmc_assert(h_insert(h, 3)); - - it = h_iter_end(h); - - cmc_assert_equals(size_t, h->count - 1, it.cursor); - cmc_assert_equals(bool, false, it.start); - - h_free(h); - }); - - CMC_CREATE_TEST(PFX##_iter_at_start(), { - struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); - - cmc_assert_not_equals(ptr, NULL, h); - - struct heap_iter it = h_iter_start(h); - - // Empty checks - cmc_assert(h_iter_at_start(&it)); - it = h_iter_end(h); - cmc_assert(h_iter_at_start(&it)); - - // Non-empty check - cmc_assert(h_insert(h, 1)); - it = h_iter_end(h); - cmc_assert(!h_iter_at_start(&it)); - it = h_iter_start(h); - cmc_assert(h_iter_at_start(&it)); - - h_free(h); - }); - - CMC_CREATE_TEST(PFX##_iter_at_end(), { - struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); - - cmc_assert_not_equals(ptr, NULL, h); - - struct heap_iter it = h_iter_start(h); - - // Empty check - cmc_assert(h_iter_at_end(&it)); - it = h_iter_end(h); - cmc_assert(h_iter_at_end(&it)); - - // Non-empty check - cmc_assert(h_insert(h, 1)); - it = h_iter_end(h); - cmc_assert(h_iter_at_end(&it)); - it = h_iter_start(h); - cmc_assert(!h_iter_at_end(&it)); - - h_free(h); - }); - - CMC_CREATE_TEST(PFX##_iter_to_start(), { - struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); - - cmc_assert_not_equals(ptr, NULL, h); - - struct heap_iter it = h_iter_start(h); - - cmc_assert(!h_iter_to_start(&it)); - - for (size_t i = 1; i <= 100; i++) - { - if (i % 2 == 0) - h_insert(h, i); - else - h_insert(h, i); - } - - cmc_assert_equals(size_t, 100, h->count); - - it = h_iter_end(h); - cmc_assert(!h_iter_at_start(&it)); - cmc_assert(h_iter_at_end(&it)); - cmc_assert_equals(size_t, 99, it.cursor); - - cmc_assert(h_iter_to_start(&it)); - cmc_assert(h_iter_at_start(&it)); - cmc_assert(!h_iter_at_end(&it)); - cmc_assert_equals(size_t, 0, it.cursor); - - h_free(h); - }); - - CMC_CREATE_TEST(PFX##_iter_to_end(), { - struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); - - cmc_assert_not_equals(ptr, NULL, h); - - struct heap_iter it = h_iter_end(h); - - cmc_assert(!h_iter_to_end(&it)); - - for (size_t i = 1; i <= 100; i++) - { - if (i % 2 == 0) - h_insert(h, i); - else - h_insert(h, i); - } - - it = h_iter_start(h); - cmc_assert(h_iter_at_start(&it)); - cmc_assert(!h_iter_at_end(&it)); - - cmc_assert(h_iter_to_end(&it)); - cmc_assert(!h_iter_at_start(&it)); - cmc_assert(h_iter_at_end(&it)); - - h_free(h); - }); - - CMC_CREATE_TEST(PFX##_iter_next(), { - struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); - - cmc_assert_not_equals(ptr, NULL, h); - - struct heap_iter it = h_iter_start(h); - - cmc_assert(!h_iter_next(&it)); - - for (size_t i = 1; i <= 1000; i++) - { - if (i % 2 == 0) - h_insert(h, i); - else - h_insert(h, i); - } - - size_t sum = 0; - for (it = h_iter_start(h); !h_iter_at_end(&it); h_iter_next(&it)) - { - sum += h_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - - h_iter_to_start(&it); - do - { - sum += h_iter_value(&it); - } while (h_iter_next(&it)); - - cmc_assert_equals(size_t, 500500, sum); - - h_free(h); - }); - - CMC_CREATE_TEST(PFX##_iter_prev(), { - struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); - - cmc_assert_not_equals(ptr, NULL, h); - - struct heap_iter it = h_iter_end(h); - - cmc_assert(!h_iter_prev(&it)); - - for (size_t i = 1; i <= 1000; i++) - { - if (i % 2 == 0) - h_insert(h, i); - else - h_insert(h, i); - } - - size_t sum = 0; - for (it = h_iter_end(h); !h_iter_at_start(&it); h_iter_prev(&it)) - { - sum += h_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - - h_iter_to_end(&it); - do - { - sum += h_iter_value(&it); - } while (h_iter_prev(&it)); - - cmc_assert_equals(size_t, 500500, sum); - - h_free(h); - }); - - CMC_CREATE_TEST(PFX##_iter_advance(), { - struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); - - cmc_assert_not_equals(ptr, NULL, h); - - struct heap_iter it = h_iter_start(h); - - cmc_assert(!h_iter_advance(&it, 1)); - - for (size_t i = 1; i <= 1000; i++) - h_insert(h, i); - - it = h_iter_start(h); - - cmc_assert(!h_iter_advance(&it, 0)); - cmc_assert(!h_iter_advance(&it, h->count)); - - size_t sum = 0; - for (it = h_iter_start(h);;) - { - sum += h_iter_value(&it); - - if (!h_iter_advance(&it, 2)) - break; - - cmc_assert_equals(size_t, 0, h_iter_index(&it) % 2); - } - - cmc_assert(h_iter_to_start(&it)); - cmc_assert(h_iter_next(&it)); - - cmc_assert_equals(size_t, 1, h_iter_index(&it)); - - for (;;) - { - sum += h_iter_value(&it); - - if (!h_iter_advance(&it, 2)) - break; - - cmc_assert_equals(size_t, 1, h_iter_index(&it) % 2); - } - - cmc_assert_equals(size_t, 500500, sum); - - h_iter_to_start(&it); - cmc_assert(h_iter_advance(&it, h->count - 1)); - - h_free(h); - }); - - CMC_CREATE_TEST(PFX##_iter_rewind(), { - struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); - - cmc_assert_not_equals(ptr, NULL, h); - - struct heap_iter it = h_iter_end(h); - - cmc_assert(!h_iter_rewind(&it, 1)); - - for (size_t i = 0; i <= 1000; i++) - h_insert(h, i); - - it = h_iter_end(h); - - cmc_assert(!h_iter_rewind(&it, 0)); - cmc_assert(!h_iter_rewind(&it, h->count)); - - size_t sum = 0; - for (it = h_iter_end(h);;) - { - sum += h_iter_value(&it); - - if (!h_iter_rewind(&it, 2)) - break; - - cmc_assert_equals(size_t, 0, h_iter_index(&it) % 2); - } - - cmc_assert(h_iter_to_end(&it)); - cmc_assert(h_iter_prev(&it)); - - cmc_assert_equals(size_t, h->count - 2, h_iter_index(&it)); - - for (;;) - { - sum += h_iter_value(&it); - - if (!h_iter_rewind(&it, 2)) - break; - - cmc_assert_equals(size_t, 1, h_iter_index(&it) % 2); - } - - cmc_assert_equals(size_t, 500500, sum); - - h_iter_to_end(&it); - cmc_assert(h_iter_rewind(&it, h->count - 1)); - - h_free(h); - }); - - CMC_CREATE_TEST(PFX##_iter_go_to(), { - struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); - - cmc_assert_not_equals(ptr, NULL, h); - - struct heap_iter it = h_iter_end(h); - cmc_assert(!h_iter_go_to(&it, 0)); - - it = h_iter_start(h); - cmc_assert(!h_iter_go_to(&it, 0)); - - for (size_t i = 0; i <= 1000; i++) - h_insert(h, i); - - cmc_assert_equals(size_t, 1001, h->count); - - it = h_iter_start(h); - - size_t sum = 0; - for (size_t i = 0; i < 1001; i++) - { - h_iter_go_to(&it, i); - - sum += h_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - for (size_t i = 1001; i > 0; i--) - { - cmc_assert(h_iter_go_to(&it, i - 1)); - - sum += h_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - h_free(h); - }); - - CMC_CREATE_TEST(PFX##_iter_value(), { - struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); - - cmc_assert_not_equals(ptr, NULL, h); - - struct heap_iter it = h_iter_end(h); - - cmc_assert_equals(size_t, (size_t){ 0 }, h_iter_value(&it)); - - cmc_assert(h_insert(h, 1)); - cmc_assert(h_insert(h, 3)); - cmc_assert(h_insert(h, 2)); - - it = h_iter_start(h); - - cmc_assert_equals(size_t, 3, h_iter_value(&it)); - - h_free(h); - }); - - CMC_CREATE_TEST(PFX##_iter_index(), { - struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval); - - cmc_assert_not_equals(ptr, NULL, h); - - for (size_t i = 0; i <= 1000; i++) - h_insert(h, i); - - struct heap_iter it = h_iter_start(h); - - for (size_t i = 0; i < 1001; i++) - { - cmc_assert_equals(size_t, i, h_iter_index(&it)); - h_iter_next(&it); - } - - it = h_iter_end(h); - for (size_t i = 1001; i > 0; i--) - { - cmc_assert_equals(size_t, i - 1, h_iter_index(&it)); - h_iter_prev(&it); - } - - h_free(h); - }); -}); - -#ifdef CMC_TEST_MAIN -int main(void) -{ - int result = CMCHeap() + CMCHeapIter(); - - printf(" +---------------------------------------------------------------+"); - printf("\n"); - printf(" | CMCHeap Suit : %-49s |\n", result == 0 ? "PASSED" : "FAILED"); - printf(" +---------------------------------------------------------------+"); - printf("\n\n\n"); - - return result; -} -#endif - -#endif /* CMC_TESTS_UNT_CMC_EAP_H */ diff --git a/tests/unt/unt_cmc_intervalheap.h b/tests/unt/unt_cmc_intervalheap.h deleted file mode 100644 index 4863ca7..0000000 --- a/tests/unt/unt_cmc_intervalheap.h +++ /dev/null @@ -1,1054 +0,0 @@ -#ifndef CMC_TESTS_UNT_CMC_NTERVALHEAP_H -#define CMC_TESTS_UNT_CMC_NTERVALHEAP_H - -#include "utl.h" - -#include "tst_cmc_intervalheap.h" - -struct intervalheap_fval *ih_fval = &(struct intervalheap_fval){ - .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp -}; - -struct intervalheap_fval *ih_fval_counter = &(struct intervalheap_fval){ - .cmp = v_c_cmp, .cpy = v_c_cpy, .str = v_c_str, .free = v_c_free, .hash = v_c_hash, .pri = v_c_pri -}; - -struct cmc_alloc_node *ih_alloc_node = - &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free }; - -CMC_CREATE_UNIT(CMCIntervalHeap, true, { - CMC_CREATE_TEST(PFX##_new(), { - struct intervalheap *ih = ih_new(1000000, ih_fval); - - cmc_assert_not_equals(ptr, NULL, ih); - cmc_assert_not_equals(ptr, NULL, ih->buffer); - cmc_assert_equals(size_t, 500000, ih_capacity(ih)); - cmc_assert_equals(size_t, 0, ih_count(ih)); - - ih_free(ih); - - ih = ih_new(0, ih_fval); - - cmc_assert_equals(ptr, NULL, ih); - - ih = ih_new(UINT64_MAX, ih_fval); - - cmc_assert_equals(ptr, NULL, ih); - - ih = ih_new(1, ih_fval); - - cmc_assert_not_equals(ptr, NULL, ih); - cmc_assert_equals(size_t, 1, ih_capacity(ih)); - - ih_free(ih); - - ih = ih_new(2, ih_fval); - - cmc_assert_not_equals(ptr, NULL, ih); - cmc_assert_equals(size_t, 1, ih_capacity(ih)); - - ih_free(ih); - - ih = ih_new(3, ih_fval); - - cmc_assert_not_equals(ptr, NULL, ih); - cmc_assert_equals(size_t, 2, ih_capacity(ih)); - - ih_free(ih); - - ih = ih_new(4, ih_fval); - cmc_assert_not_equals(ptr, NULL, ih); - cmc_assert_equals(size_t, 2, ih_capacity(ih)); - - ih_free(ih); - }); - - CMC_CREATE_TEST(PFX##_new_custom(), { - struct intervalheap *ih = ih_new_custom(1000000, ih_fval, ih_alloc_node, callbacks); - - cmc_assert_not_equals(ptr, NULL, ih); - cmc_assert_not_equals(ptr, NULL, ih->buffer); - cmc_assert_equals(size_t, 500000, ih_capacity(ih)); - cmc_assert_equals(size_t, 0, ih_count(ih)); - cmc_assert_equals(ptr, ih_alloc_node, ih->alloc); - cmc_assert_equals(ptr, callbacks, ih->callbacks); - - ih_free(ih); - - ih = ih_new_custom(0, ih_fval, NULL, NULL); - - cmc_assert_equals(ptr, NULL, ih); - - ih = ih_new_custom(UINT64_MAX, ih_fval, NULL, NULL); - - cmc_assert_equals(ptr, NULL, ih); - - ih = ih_new_custom(1, ih_fval, NULL, NULL); - - cmc_assert_not_equals(ptr, NULL, ih); - cmc_assert_equals(size_t, 1, ih_capacity(ih)); - cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, ih->alloc->malloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, ih->alloc->calloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, ih->alloc->realloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.free, ih->alloc->free); - cmc_assert_equals(ptr, NULL, ih->callbacks); - - ih_free(ih); - - ih = ih_new_custom(2, ih_fval, NULL, NULL); - - cmc_assert_not_equals(ptr, NULL, ih); - cmc_assert_equals(size_t, 1, ih_capacity(ih)); - - ih_free(ih); - - ih = ih_new_custom(3, ih_fval, NULL, NULL); - - cmc_assert_not_equals(ptr, NULL, ih); - cmc_assert_equals(size_t, 2, ih_capacity(ih)); - - ih_free(ih); - - ih = ih_new_custom(4, ih_fval, NULL, NULL); - - cmc_assert_not_equals(ptr, NULL, ih); - cmc_assert_equals(size_t, 2, ih_capacity(ih)); - - ih_free(ih); - }); - - CMC_CREATE_TEST(PFX##_clear(), { - v_total_free = 0; - struct intervalheap *ih = ih_new(100, ih_fval); - - cmc_assert_not_equals(ptr, NULL, ih); - - for (size_t i = 0; i < 50; i++) - ih_insert(ih, i); - - cmc_assert_equals(size_t, 50, ih_count(ih)); - - ih_clear(ih); - - cmc_assert_equals(size_t, 0, ih_count(ih)); - cmc_assert_equals(size_t, 50, ih_capacity(ih)); - - ih_free(ih); - - ih = ih_new(100, ih_fval_counter); - - ih_insert(ih, 10); - ih_clear(ih); - - cmc_assert_equals(int32_t, 1, v_total_free); - - for (size_t i = 0; i < 10000; i++) - ih_insert(ih, i); - - cmc_assert_equals(size_t, 10000, ih_count(ih)); - - ih_clear(ih); - - cmc_assert_equals(int32_t, 10001, v_total_free); - - size_t sum = 0; - for (size_t i = 0; i < ih->capacity; i++) - sum += ih->buffer[i / 2][i % 2]; - - cmc_assert_equals(size_t, 0, sum); - - ih_free(ih); - - cmc_assert_equals(int32_t, 10001, v_total_free); - - v_total_free = 0; - }); - - CMC_CREATE_TEST(PFX##_free(), { - v_total_free = 0; - struct intervalheap *ih = ih_new(100, ih_fval_counter); - - cmc_assert_not_equals(ptr, NULL, ih); - - ih_insert(ih, 10); - ih_free(ih); - - cmc_assert_equals(int32_t, 1, v_total_free); - - ih = ih_new(100, ih_fval_counter); - - for (size_t i = 0; i < 10000; i++) - ih_insert(ih, i); - - ih_free(ih); - - cmc_assert_equals(int32_t, 10001, v_total_free); - - v_total_free = 0; - }); - - CMC_CREATE_TEST(PFX##_customize(), { - struct intervalheap *ih = ih_new(100, ih_fval); - - ih->flag = CMC_FLAG_ERROR; - ih_customize(ih, ih_alloc_node, callbacks); - - cmc_assert_equals(ptr, ih_alloc_node, ih->alloc); - cmc_assert_equals(ptr, callbacks, ih->callbacks); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ih->flag); - - ih->flag = CMC_FLAG_ERROR; - ih_customize(ih, NULL, NULL); - - cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, ih->alloc->malloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, ih->alloc->calloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, ih->alloc->realloc); - cmc_assert_equals(ptr, cmc_alloc_node_default.free, ih->alloc->free); - cmc_assert_equals(ptr, NULL, ih->callbacks); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ih->flag); - - ih_free(ih); - }); - - CMC_CREATE_TEST(PFX##_insert(), { - total_create = 0; - struct intervalheap *ih = ih_new(100, ih_fval); - - cmc_assert_not_equals(ptr, NULL, ih); - - for (size_t i = 0; i < 100; i++) - ih_insert(ih, 10); - - cmc_assert_equals(size_t, 100, ih_count(ih)); - - ih_clear(ih); - - cmc_assert(ih_insert(ih, 1)); - cmc_assert(ih_insert(ih, 0)); - - cmc_assert_equals(size_t, 2, ih_count(ih)); - - ih_free(ih); - - // callbacks - ih = ih_new_custom(100, ih_fval, NULL, callbacks); - - for (size_t i = 0; i < 10000; i++) - ih_insert(ih, i); - - cmc_assert_equals(size_t, 10000, ih_count(ih)); - cmc_assert_equals(int32_t, 10000, total_create); - - ih_free(ih); - - // max - ih = ih_new(1, ih_fval); - - cmc_assert(ih_insert(ih, 0)); - cmc_assert(ih_insert(ih, 1)); - cmc_assert(ih_insert(ih, 2)); - - cmc_assert_equals(size_t, 2, ih_max(ih)); - - ih_free(ih); - - // min - ih = ih_new(1, ih_fval); - - cmc_assert(ih_insert(ih, 0)); - cmc_assert(ih_insert(ih, 1)); - cmc_assert(ih_insert(ih, 2)); - - cmc_assert_equals(size_t, 0, ih_min(ih)); - - ih_free(ih); - - // remove_max, remove_min - ih = ih_new(100, ih_fval); - - cmc_assert_not_equals(ptr, NULL, ih); - - cmc_assert(ih_insert(ih, 2)); - cmc_assert_equals(size_t, 2, ih->buffer[0][0]); - - cmc_assert(ih_insert(ih, 1)); - cmc_assert_equals(size_t, 1, ih->buffer[0][0]); - cmc_assert_equals(size_t, 2, ih->buffer[0][1]); - - cmc_assert(ih_remove_min(ih)); - cmc_assert_equals(size_t, 2, ih->buffer[0][0]); - - cmc_assert(ih_insert(ih, 1)); - cmc_assert_equals(size_t, 1, ih->buffer[0][0]); - cmc_assert_equals(size_t, 2, ih->buffer[0][1]); - - cmc_assert(ih_remove_max(ih)); - cmc_assert_equals(size_t, 1, ih->buffer[0][0]); - - ih_free(ih); - total_create = 0; - }); - - CMC_CREATE_TEST(PFX##_remove_max(), { - total_delete = 0; - struct intervalheap *ih = ih_new_custom(100, ih_fval, NULL, callbacks); - - // count == 0 - cmc_assert(!ih_remove_max(ih)); - - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ih->flag); - - // count == 1 - cmc_assert(ih_insert(ih, 10)); - ih->flag = CMC_FLAG_ERROR; - cmc_assert(ih_remove_max(ih)); - - cmc_assert_equals(int32_t, 1, total_delete); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ih->flag); - - for (size_t i = 1; i <= 1000; i++) - ih_insert(ih, i); - - for (size_t i = 1000; i > 0; i--) - { - cmc_assert_equals(size_t, i, ih_max(ih)); - cmc_assert(ih_remove_max(ih)); - } - - cmc_assert_equals(size_t, 0, ih_count(ih)); - - for (size_t i = 1; i <= 1000; i++) - { - ih_insert(ih, i % 50); - } - - cmc_assert_equals(size_t, 1000, ih_count(ih)); - - for (int i = 49; i >= 0; i--) - { - for (size_t j = 0; j < 20; j++) - { - cmc_assert_equals(size_t, (size_t)i, ih_max(ih)); - cmc_assert(ih_remove_max(ih)); - } - } - - ih_free(ih); - total_delete = 0; - }); - - CMC_CREATE_TEST(PFX##_remove_min(), { - total_delete = 0; - struct intervalheap *ih = ih_new_custom(100, ih_fval, NULL, callbacks); - - // count == 0 - cmc_assert(!ih_remove_min(ih)); - - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ih->flag); - - // count == 1 - cmc_assert(ih_insert(ih, 10)); - ih->flag = CMC_FLAG_ERROR; - cmc_assert(ih_remove_min(ih)); - - cmc_assert_equals(int32_t, 1, total_delete); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ih->flag); - - for (size_t i = 1000; i >= 1; i--) - ih_insert(ih, i); - - for (size_t i = 1; i <= 1000; i++) - { - cmc_assert_equals(size_t, i, ih_min(ih)); - cmc_assert(ih_remove_min(ih)); - } - - cmc_assert_equals(size_t, 0, ih_count(ih)); - - for (size_t i = 1000; i >= 1; i--) - { - ih_insert(ih, i % 50); - } - - cmc_assert_equals(size_t, 1000, ih_count(ih)); - - for (int i = 0; i <= 49; i++) - { - for (size_t j = 0; j < 20; j++) - { - cmc_assert_equals(size_t, (size_t)i, ih_min(ih)); - cmc_assert(ih_remove_min(ih)); - } - } - - ih_free(ih); - total_delete = 0; - }); - - CMC_CREATE_TEST(PFX##_remove_max() + PFX##_remove_min(), { - struct intervalheap *ih = ih_new(100, ih_fval); - - for (size_t i = 1; i <= 10000; i++) - { - ih_insert(ih, i % 50); - } - - cmc_assert_equals(size_t, 10000, ih_count(ih)); - - // i = min - // j = max - for (size_t i = 0, j = 49; i < j; i++, j--) - { - for (size_t k = 0; k < 200; k++) - { - cmc_assert_equals(size_t, i, ih_min(ih)); - cmc_assert_equals(size_t, j, ih_max(ih)); - cmc_assert(ih_remove_min(ih)); - cmc_assert(ih_remove_max(ih)); - } - } - - cmc_assert_equals(size_t, 0, ih_count(ih)); - - ih_free(ih); - }); - - CMC_CREATE_TEST(buffer_growth[capacity = 1], { - struct intervalheap *ih = ih_new(1, ih_fval); - - cmc_assert_not_equals(ptr, NULL, ih); - - for (size_t i = 0; i < 50; i++) - cmc_assert(ih_insert(ih, i)); - - cmc_assert_equals(size_t, 50, ih_count(ih)); - cmc_assert_greater(size_t, 50, ih_capacity(ih) * 2); - - ih_free(ih); - }); - - CMC_CREATE_TEST(flags, { - struct intervalheap *ih = ih_new(100, ih_fval); - - cmc_assert_not_equals(ptr, NULL, ih); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih)); - - ih->flag = CMC_FLAG_ERROR; - - // clear - ih_clear(ih); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih)); - - // customize - ih->flag = CMC_FLAG_ERROR; - ih_customize(ih, NULL, NULL); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih)); - - // insert - ih->flag = CMC_FLAG_ERROR; - cmc_assert(ih_insert(ih, 10)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih)); - - // remove_max - cmc_assert(ih_remove_max(ih)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih)); - cmc_assert(!ih_remove_max(ih)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ih_flag(ih)); - - // remove min - cmc_assert(ih_insert(ih, 10)); - cmc_assert(ih_remove_min(ih)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih)); - cmc_assert(!ih_remove_min(ih)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ih_flag(ih)); - - // update_max - cmc_assert(!ih_update_max(ih, 20)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ih_flag(ih)); - cmc_assert(ih_insert(ih, 10)); - ih->flag = CMC_FLAG_ERROR; - cmc_assert(ih_update_max(ih, 20)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih)); - - // update_min - ih->flag = CMC_FLAG_ERROR; - cmc_assert(ih_update_min(ih, 20)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih)); - cmc_assert(ih_remove_min(ih)); - ih->flag = CMC_FLAG_ERROR; - cmc_assert(!ih_update_max(ih, 20)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ih_flag(ih)); - - // max min - ih->flag = CMC_FLAG_ERROR; - cmc_assert_equals(size_t, (size_t){ 0 }, ih_max(ih)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ih_flag(ih)); - - ih->flag = CMC_FLAG_ERROR; - cmc_assert_equals(size_t, (size_t){ 0 }, ih_min(ih)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ih_flag(ih)); - - cmc_assert(ih_insert(ih, 10)); - ih->flag = CMC_FLAG_ERROR; - cmc_assert_equals(size_t, 10, ih_max(ih)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih)); - - ih->flag = CMC_FLAG_ERROR; - cmc_assert_equals(size_t, 10, ih_min(ih)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih)); - - // contains - ih->flag = CMC_FLAG_ERROR; - cmc_assert(ih_contains(ih, 10)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih)); - - // copy_of - ih->flag = CMC_FLAG_ERROR; - struct intervalheap *ih2 = ih_copy_of(ih); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih2)); - - // equals - ih->flag = CMC_FLAG_ERROR; - ih2->flag = CMC_FLAG_ERROR; - cmc_assert(ih_equals(ih, ih2)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih2)); - - ih_free(ih); - ih_free(ih2); - }); - - CMC_CREATE_TEST(callbacks, { - struct intervalheap *ih = ih_new_custom(100, ih_fval, NULL, callbacks); - - cmc_assert_not_equals(ptr, NULL, ih); - - total_create = 0; - total_read = 0; - total_update = 0; - total_delete = 0; - total_resize = 0; - - cmc_assert(ih_insert(ih, 10)); - cmc_assert_equals(int32_t, 1, total_create); - - cmc_assert(ih_remove_max(ih)); - cmc_assert_equals(int32_t, 1, total_delete); - - cmc_assert(ih_insert(ih, 10)); - cmc_assert_equals(int32_t, 2, total_create); - - cmc_assert(ih_remove_min(ih)); - cmc_assert_equals(int32_t, 2, total_delete); - - cmc_assert(ih_insert(ih, 1)); - cmc_assert(ih_insert(ih, 2)); - cmc_assert_equals(int32_t, 4, total_create); - - cmc_assert(ih_update_max(ih, 1)); - cmc_assert_equals(int32_t, 1, total_update); - - cmc_assert(ih_update_min(ih, 2)); - cmc_assert_equals(int32_t, 2, total_update); - - cmc_assert_equals(size_t, 2, ih_max(ih)); - cmc_assert_equals(int32_t, 1, total_read); - - cmc_assert_equals(size_t, 1, ih_min(ih)); - cmc_assert_equals(int32_t, 2, total_read); - - cmc_assert(ih_contains(ih, 1)); - cmc_assert_equals(int32_t, 3, total_read); - - cmc_assert(ih_resize(ih, 1000)); - cmc_assert_equals(int32_t, 1, total_resize); - - cmc_assert(ih_resize(ih, 50)); - cmc_assert_equals(int32_t, 2, total_resize); - - cmc_assert_equals(int32_t, 4, total_create); - cmc_assert_equals(int32_t, 3, total_read); - cmc_assert_equals(int32_t, 2, total_update); - cmc_assert_equals(int32_t, 2, total_delete); - cmc_assert_equals(int32_t, 2, total_resize); - - ih_customize(ih, NULL, NULL); - - cmc_assert_equals(ptr, NULL, ih->callbacks); - - ih_clear(ih); - cmc_assert(ih_insert(ih, 10)); - cmc_assert(ih_remove_max(ih)); - cmc_assert(ih_insert(ih, 10)); - cmc_assert(ih_remove_min(ih)); - cmc_assert(ih_insert(ih, 1)); - cmc_assert(ih_insert(ih, 2)); - cmc_assert(ih_update_max(ih, 1)); - cmc_assert(ih_update_min(ih, 2)); - cmc_assert_equals(size_t, 2, ih_max(ih)); - cmc_assert_equals(size_t, 1, ih_min(ih)); - cmc_assert(ih_contains(ih, 1)); - cmc_assert(ih_resize(ih, 1000)); - cmc_assert(ih_resize(ih, 50)); - - cmc_assert_equals(int32_t, 4, total_create); - cmc_assert_equals(int32_t, 3, total_read); - cmc_assert_equals(int32_t, 2, total_update); - cmc_assert_equals(int32_t, 2, total_delete); - cmc_assert_equals(int32_t, 2, total_resize); - - cmc_assert_equals(ptr, NULL, ih->callbacks); - - ih_free(ih); - - total_create = 0; - total_read = 0; - total_update = 0; - total_delete = 0; - total_resize = 0; - }); -}); - -CMC_CREATE_UNIT(CMCIntervalHeapIter, true, { - CMC_CREATE_TEST(PFX##_iter_start(), { - struct intervalheap *ih = ih_new(100, ih_fval); - - cmc_assert_not_equals(ptr, NULL, ih); - - struct intervalheap_iter it = ih_iter_start(ih); - - cmc_assert_equals(ptr, ih, it.target); - cmc_assert_equals(size_t, 0, it.cursor); - cmc_assert_equals(bool, true, it.start); - cmc_assert_equals(bool, true, it.end); - - cmc_assert(ih_iter_at_start(&it)); - cmc_assert(ih_iter_at_end(&it)); - - cmc_assert(ih_insert(ih, 1)); - cmc_assert(ih_insert(ih, 2)); - - it = ih_iter_start(ih); - - cmc_assert_equals(size_t, 0, it.cursor); - cmc_assert_equals(bool, false, it.end); - - ih_free(ih); - }); - - CMC_CREATE_TEST(PFX##_iter_end(), { - struct intervalheap *ih = ih_new(100, ih_fval); - - cmc_assert_not_equals(ptr, NULL, ih); - - struct intervalheap_iter it = ih_iter_end(ih); - - cmc_assert_equals(ptr, ih, it.target); - cmc_assert_equals(size_t, 0, it.cursor); - cmc_assert_equals(bool, true, it.start); - cmc_assert_equals(bool, true, it.end); - - cmc_assert(ih_iter_at_start(&it)); - cmc_assert(ih_iter_at_end(&it)); - - cmc_assert(ih_insert(ih, 1)); - cmc_assert(ih_insert(ih, 2)); - cmc_assert(ih_insert(ih, 3)); - - it = ih_iter_end(ih); - - cmc_assert_equals(size_t, ih->count - 1, it.cursor); - cmc_assert_equals(bool, false, it.start); - - ih_free(ih); - }); - - CMC_CREATE_TEST(PFX##_iter_at_start(), { - struct intervalheap *ih = ih_new(100, ih_fval); - - cmc_assert_not_equals(ptr, NULL, ih); - - struct intervalheap_iter it = ih_iter_start(ih); - - // Empty checks - cmc_assert(ih_iter_at_start(&it)); - it = ih_iter_end(ih); - cmc_assert(ih_iter_at_start(&it)); - - // Non-empty check - cmc_assert(ih_insert(ih, 1)); - it = ih_iter_end(ih); - cmc_assert(!ih_iter_at_start(&it)); - it = ih_iter_start(ih); - cmc_assert(ih_iter_at_start(&it)); - - ih_free(ih); - }); - - CMC_CREATE_TEST(PFX##_iter_at_end(), { - struct intervalheap *ih = ih_new(100, ih_fval); - - cmc_assert_not_equals(ptr, NULL, ih); - - struct intervalheap_iter it = ih_iter_start(ih); - - // Empty check - cmc_assert(ih_iter_at_end(&it)); - it = ih_iter_end(ih); - cmc_assert(ih_iter_at_end(&it)); - - // Non-empty check - cmc_assert(ih_insert(ih, 1)); - it = ih_iter_end(ih); - cmc_assert(ih_iter_at_end(&it)); - it = ih_iter_start(ih); - cmc_assert(!ih_iter_at_end(&it)); - - ih_free(ih); - }); - - CMC_CREATE_TEST(PFX##_iter_to_start(), { - struct intervalheap *ih = ih_new(100, ih_fval); - - cmc_assert_not_equals(ptr, NULL, ih); - - struct intervalheap_iter it = ih_iter_start(ih); - - cmc_assert(!ih_iter_to_start(&it)); - - for (size_t i = 1; i <= 100; i++) - { - if (i % 2 == 0) - ih_insert(ih, i); - else - ih_insert(ih, i); - } - - cmc_assert_equals(size_t, 100, ih->count); - - it = ih_iter_end(ih); - cmc_assert(!ih_iter_at_start(&it)); - cmc_assert(ih_iter_at_end(&it)); - cmc_assert_equals(size_t, 99, it.cursor); - - cmc_assert(ih_iter_to_start(&it)); - cmc_assert(ih_iter_at_start(&it)); - cmc_assert(!ih_iter_at_end(&it)); - cmc_assert_equals(size_t, 0, it.cursor); - - ih_free(ih); - }); - - CMC_CREATE_TEST(PFX##_iter_to_end(), { - struct intervalheap *ih = ih_new(100, ih_fval); - - cmc_assert_not_equals(ptr, NULL, ih); - - struct intervalheap_iter it = ih_iter_end(ih); - - cmc_assert(!ih_iter_to_end(&it)); - - for (size_t i = 1; i <= 100; i++) - { - if (i % 2 == 0) - ih_insert(ih, i); - else - ih_insert(ih, i); - } - - it = ih_iter_start(ih); - cmc_assert(ih_iter_at_start(&it)); - cmc_assert(!ih_iter_at_end(&it)); - - cmc_assert(ih_iter_to_end(&it)); - cmc_assert(!ih_iter_at_start(&it)); - cmc_assert(ih_iter_at_end(&it)); - - ih_free(ih); - }); - - CMC_CREATE_TEST(PFX##_iter_next(), { - struct intervalheap *ih = ih_new(100, ih_fval); - - cmc_assert_not_equals(ptr, NULL, ih); - - struct intervalheap_iter it = ih_iter_start(ih); - - cmc_assert(!ih_iter_next(&it)); - - for (size_t i = 1; i <= 1000; i++) - { - if (i % 2 == 0) - ih_insert(ih, i); - else - ih_insert(ih, i); - } - - size_t sum = 0; - for (it = ih_iter_start(ih); !ih_iter_at_end(&it); ih_iter_next(&it)) - { - sum += ih_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - - ih_iter_to_start(&it); - do - { - sum += ih_iter_value(&it); - } while (ih_iter_next(&it)); - - cmc_assert_equals(size_t, 500500, sum); - - ih_free(ih); - }); - - CMC_CREATE_TEST(PFX##_iter_prev(), { - struct intervalheap *ih = ih_new(100, ih_fval); - - cmc_assert_not_equals(ptr, NULL, ih); - - struct intervalheap_iter it = ih_iter_end(ih); - - cmc_assert(!ih_iter_prev(&it)); - - for (size_t i = 1; i <= 1000; i++) - { - if (i % 2 == 0) - ih_insert(ih, i); - else - ih_insert(ih, i); - } - - size_t sum = 0; - for (it = ih_iter_end(ih); !ih_iter_at_start(&it); ih_iter_prev(&it)) - { - sum += ih_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - - ih_iter_to_end(&it); - do - { - sum += ih_iter_value(&it); - } while (ih_iter_prev(&it)); - - cmc_assert_equals(size_t, 500500, sum); - - ih_free(ih); - }); - - CMC_CREATE_TEST(PFX##_iter_advance(), { - struct intervalheap *ih = ih_new(100, ih_fval); - - cmc_assert_not_equals(ptr, NULL, ih); - - struct intervalheap_iter it = ih_iter_start(ih); - - cmc_assert(!ih_iter_advance(&it, 1)); - - for (size_t i = 1; i <= 1000; i++) - ih_insert(ih, i); - - it = ih_iter_start(ih); - - cmc_assert(!ih_iter_advance(&it, 0)); - cmc_assert(!ih_iter_advance(&it, ih->count)); - - size_t sum = 0; - for (it = ih_iter_start(ih);;) - { - sum += ih_iter_value(&it); - - if (!ih_iter_advance(&it, 2)) - break; - - cmc_assert_equals(size_t, 0, ih_iter_index(&it) % 2); - } - - cmc_assert(ih_iter_to_start(&it)); - cmc_assert(ih_iter_next(&it)); - - cmc_assert_equals(size_t, 1, ih_iter_index(&it)); - - for (;;) - { - sum += ih_iter_value(&it); - - if (!ih_iter_advance(&it, 2)) - break; - - cmc_assert_equals(size_t, 1, ih_iter_index(&it) % 2); - } - - cmc_assert_equals(size_t, 500500, sum); - - ih_iter_to_start(&it); - cmc_assert(ih_iter_advance(&it, ih->count - 1)); - - ih_free(ih); - }); - - CMC_CREATE_TEST(PFX##_iter_rewind(), { - struct intervalheap *ih = ih_new(100, ih_fval); - - cmc_assert_not_equals(ptr, NULL, ih); - - struct intervalheap_iter it = ih_iter_end(ih); - - cmc_assert(!ih_iter_rewind(&it, 1)); - - for (size_t i = 0; i <= 1000; i++) - ih_insert(ih, i); - - it = ih_iter_end(ih); - - cmc_assert(!ih_iter_rewind(&it, 0)); - cmc_assert(!ih_iter_rewind(&it, ih->count)); - - size_t sum = 0; - for (it = ih_iter_end(ih);;) - { - sum += ih_iter_value(&it); - - if (!ih_iter_rewind(&it, 2)) - break; - - cmc_assert_equals(size_t, 0, ih_iter_index(&it) % 2); - } - - cmc_assert(ih_iter_to_end(&it)); - cmc_assert(ih_iter_prev(&it)); - - cmc_assert_equals(size_t, ih->count - 2, ih_iter_index(&it)); - - for (;;) - { - sum += ih_iter_value(&it); - - if (!ih_iter_rewind(&it, 2)) - break; - - cmc_assert_equals(size_t, 1, ih_iter_index(&it) % 2); - } - - cmc_assert_equals(size_t, 500500, sum); - - ih_iter_to_end(&it); - cmc_assert(ih_iter_rewind(&it, ih->count - 1)); - - ih_free(ih); - }); - - CMC_CREATE_TEST(PFX##_iter_go_to(), { - struct intervalheap *ih = ih_new(100, ih_fval); - - cmc_assert_not_equals(ptr, NULL, ih); - - struct intervalheap_iter it = ih_iter_end(ih); - cmc_assert(!ih_iter_go_to(&it, 0)); - - it = ih_iter_start(ih); - cmc_assert(!ih_iter_go_to(&it, 0)); - - for (size_t i = 0; i <= 1000; i++) - ih_insert(ih, i); - - cmc_assert_equals(size_t, 1001, ih->count); - - it = ih_iter_start(ih); - - size_t sum = 0; - for (size_t i = 0; i < 1001; i++) - { - ih_iter_go_to(&it, i); - - sum += ih_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - for (size_t i = 1001; i > 0; i--) - { - cmc_assert(ih_iter_go_to(&it, i - 1)); - - sum += ih_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - ih_free(ih); - }); - - CMC_CREATE_TEST(PFX##_iter_value(), { - struct intervalheap *ih = ih_new(100, ih_fval); - - cmc_assert_not_equals(ptr, NULL, ih); - - struct intervalheap_iter it = ih_iter_end(ih); - - cmc_assert_equals(size_t, (size_t){ 0 }, ih_iter_value(&it)); - - cmc_assert(ih_insert(ih, 1)); - cmc_assert(ih_insert(ih, 3)); - cmc_assert(ih_insert(ih, 2)); - - it = ih_iter_start(ih); - - cmc_assert_equals(size_t, 1, ih_iter_value(&it)); - cmc_assert(ih_iter_next(&it)); - cmc_assert_equals(size_t, 3, ih_iter_value(&it)); - - ih_free(ih); - }); - - CMC_CREATE_TEST(PFX##_iter_index(), { - struct intervalheap *ih = ih_new(100, ih_fval); - - cmc_assert_not_equals(ptr, NULL, ih); - - for (size_t i = 0; i <= 1000; i++) - ih_insert(ih, i); - - struct intervalheap_iter it = ih_iter_start(ih); - - for (size_t i = 0; i < 1001; i++) - { - cmc_assert_equals(size_t, i, ih_iter_index(&it)); - ih_iter_next(&it); - } - - it = ih_iter_end(ih); - for (size_t i = 1001; i > 0; i--) - { - cmc_assert_equals(size_t, i - 1, ih_iter_index(&it)); - ih_iter_prev(&it); - } - - ih_free(ih); - }); -}); - -#ifdef CMC_TEST_MAIN -int main(void) -{ - int result = CMCIntervalHeap() + CMCIntervalHeapIter(); - - printf(" +---------------------------------------------------------------+"); - printf("\n"); - printf(" | CMCIntervalHeap Suit : %-41s |\n", result == 0 ? "PASSED" : "FAILED"); - printf(" +---------------------------------------------------------------+"); - printf("\n\n\n"); - - return result; -} -#endif - -#endif /* CMC_TESTS_UNT_CMC_NTERVALHEAP_H */ diff --git a/tests/unt/unt_cmc_linkedlist.h b/tests/unt/unt_cmc_linkedlist.h deleted file mode 100644 index 074ee42..0000000 --- a/tests/unt/unt_cmc_linkedlist.h +++ /dev/null @@ -1,814 +0,0 @@ -#ifndef CMC_TESTS_UNT_CMC_INKEDLIST_H -#define CMC_TESTS_UNT_CMC_INKEDLIST_H - -#include "utl.h" - -#include "tst_cmc_linkedlist.h" - -struct linkedlist_fval *ll_fval = &(struct linkedlist_fval){ - .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp -}; - -CMC_CREATE_UNIT(CMCLinkedList, true, { - CMC_CREATE_TEST(new, { - struct linkedlist *ll = ll_new(ll_fval); - - cmc_assert_not_equals(ptr, NULL, ll); - cmc_assert_equals(size_t, 0, ll_count(ll)); - cmc_assert_equals(ptr, NULL, ll->head); - cmc_assert_equals(ptr, NULL, ll->tail); - - ll_free(ll); - }); - - CMC_CREATE_TEST(clear[count capacity], { - struct linkedlist *ll = ll_new(ll_fval); - - cmc_assert_not_equals(ptr, NULL, ll); - - for (size_t i = 0; i < 50; i++) - ll_push_back(ll, i); - - cmc_assert_equals(size_t, 50, ll_count(ll)); - - ll_clear(ll); - - cmc_assert_equals(size_t, 0, ll_count(ll)); - - ll_free(ll); - }); - - CMC_CREATE_TEST(clear[count = 0], { - struct linkedlist *ll = ll_new(ll_fval); - - cmc_assert_not_equals(ptr, NULL, ll); - - ll_clear(ll); - - cmc_assert_equals(size_t, 0, ll_count(ll)); - - ll_free(ll); - }); - - CMC_CREATE_TEST(push_front[count], { - struct linkedlist *ll = ll_new(ll_fval); - - cmc_assert_not_equals(ptr, NULL, ll); - - ll_push_front(ll, 1); - - cmc_assert_not_equals(ptr, NULL, ll->head); - cmc_assert_not_equals(ptr, NULL, ll->tail); - cmc_assert_equals(size_t, 1, ll_count(ll)); - - ll_free(ll); - }); - - CMC_CREATE_TEST(push_front[item preservation], { - struct linkedlist *ll = ll_new(ll_fval); - - cmc_assert_not_equals(ptr, NULL, ll); - - for (size_t i = 0; i < 200; i++) - ll_push_front(ll, i); - - for (size_t i = 0; i < ll_count(ll); i++) - cmc_assert_equals(size_t, ll_get(ll, i), ll_count(ll) - i - 1); - - ll_free(ll); - }); - - CMC_CREATE_TEST(flags, { - struct linkedlist *ll = ll_new(ll_fval); - - cmc_assert_not_equals(ptr, NULL, ll); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); - - // clear - ll->flag = CMC_FLAG_ERROR; - ll_clear(ll); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); - - // customize - ll->flag = CMC_FLAG_ERROR; - ll_customize(ll, NULL, NULL); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); - - // push_front - ll->flag = CMC_FLAG_ERROR; - cmc_assert(ll_push_front(ll, 10)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); - - // push_at - ll->flag = CMC_FLAG_ERROR; - cmc_assert(ll_push_at(ll, 10, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); - cmc_assert(!ll_push_at(ll, 10, 300)); - cmc_assert_equals(int32_t, CMC_FLAG_RANGE, ll_flag(ll)); - - // push_back - ll->flag = CMC_FLAG_ERROR; - cmc_assert(ll_push_back(ll, 10)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); - - ll_clear(ll); - - // pop_front - ll->flag = CMC_FLAG_ERROR; - cmc_assert(!ll_pop_front(ll)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ll_flag(ll)); - - cmc_assert(ll_push_back(ll, 10)); - cmc_assert(ll_pop_front(ll)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); - - // pop_at - cmc_assert(!ll_pop_at(ll, 0)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ll_flag(ll)); - cmc_assert(ll_push_front(ll, 10)); - cmc_assert(!ll_pop_at(ll, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_RANGE, ll_flag(ll)); - cmc_assert(ll_pop_at(ll, 0)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); - - // pop_back - ll->flag = CMC_FLAG_ERROR; - cmc_assert(!ll_pop_front(ll)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ll_flag(ll)); - - cmc_assert(ll_push_back(ll, 10)); - cmc_assert(ll_pop_front(ll)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); - - ll_clear(ll); - - // front - ll_front(ll); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ll_flag(ll)); - cmc_assert(ll_push_front(ll, 10)); - ll->flag = CMC_FLAG_ERROR; - ll_front(ll); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); - - ll_clear(ll); - - // back - ll_back(ll); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ll_flag(ll)); - cmc_assert(ll_push_front(ll, 10)); - ll->flag = CMC_FLAG_ERROR; - ll_back(ll); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); - - ll_clear(ll); - - // get get_ref - ll_get(ll, 0); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ll_flag(ll)); - ll->flag = CMC_FLAG_ERROR; - ll_get_ref(ll, 0); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ll_flag(ll)); - - cmc_assert(ll_push_at(ll, 10, 0)); - ll->flag = CMC_FLAG_ERROR; - ll_get(ll, 0); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); - ll_get(ll, 1); - cmc_assert_equals(int32_t, CMC_FLAG_RANGE, ll_flag(ll)); - ll_get_ref(ll, 0); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); - ll_get_ref(ll, 1); - cmc_assert_equals(int32_t, CMC_FLAG_RANGE, ll_flag(ll)); - - // contains - cmc_assert(ll_contains(ll, 10)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); - - // copy_of - ll->flag = CMC_FLAG_ERROR; - struct linkedlist *ll2 = ll_copy_of(ll); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll2)); - - // equals - ll->flag = CMC_FLAG_ERROR; - ll2->flag = CMC_FLAG_ERROR; - cmc_assert(ll_equals(ll, ll2)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll2)); - - ll_clear(ll); - - // get_node - struct linkedlist_node *n = ll_get_node(ll, 0); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ll_flag(ll)); - - cmc_assert(ll_push_at(ll, 10, 0)); - n = ll_get_node(ll, 0); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); - - n = ll_get_node(ll, 1); - cmc_assert_equals(int32_t, CMC_FLAG_RANGE, ll_flag(ll)); - - // functions relative to node - ll_clear(ll); - cmc_assert(ll_push_front(ll, 10)); - n = ll_get_node(ll, 0); - cmc_assert_not_equals(ptr, NULL, n); - - // add_next - ll->flag = CMC_FLAG_ERROR; - cmc_assert(ll_add_next(ll, n, 11)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); - - // add_prev - ll->flag = CMC_FLAG_ERROR; - cmc_assert(ll_add_prev(ll, n, 9)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); - - // del_next - n = ll_next_node(n); - cmc_assert(!ll_del_next(ll, n)); - cmc_assert_equals(int32_t, CMC_FLAG_INVALID, ll_flag(ll)); - n = ll_prev_node(n); - cmc_assert(ll_del_next(ll, n)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); - - // del_prev - n = ll_prev_node(n); - cmc_assert(!ll_del_prev(ll, n)); - cmc_assert_equals(int32_t, CMC_FLAG_INVALID, ll_flag(ll)); - n = ll_next_node(n); - cmc_assert(ll_del_prev(ll, n)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); - - // del_curr - ll->flag = CMC_FLAG_ERROR; - cmc_assert(ll_del_curr(ll, n)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll)); - - ll_free(ll); - ll_free(ll2); - }); - - CMC_CREATE_TEST(callbacks, { - struct linkedlist *ll = ll_new_custom(ll_fval, NULL, callbacks); - - cmc_assert_not_equals(ptr, NULL, ll); - - total_create = 0; - total_read = 0; - total_update = 0; - total_delete = 0; - total_resize = 0; - - cmc_assert(ll_push_front(ll, 10)); - cmc_assert_equals(int32_t, 1, total_create); - - cmc_assert(ll_push_back(ll, 10)); - cmc_assert_equals(int32_t, 2, total_create); - - cmc_assert(ll_push_at(ll, 10, 1)); - cmc_assert_equals(int32_t, 3, total_create); - - cmc_assert(ll_pop_at(ll, 1)); - cmc_assert_equals(int32_t, 1, total_delete); - - cmc_assert(ll_pop_front(ll)); - cmc_assert_equals(int32_t, 2, total_delete); - - cmc_assert(ll_pop_back(ll)); - cmc_assert_equals(int32_t, 3, total_delete); - - cmc_assert(ll_push_back(ll, 10)); - cmc_assert_equals(int32_t, 4, total_create); - - cmc_assert_equals(size_t, 10, ll_front(ll)); - cmc_assert_equals(int32_t, 1, total_read); - - cmc_assert_equals(size_t, 10, ll_back(ll)); - cmc_assert_equals(int32_t, 2, total_read); - - cmc_assert_equals(size_t, 10, ll_get(ll, 0)); - cmc_assert_equals(int32_t, 3, total_read); - - cmc_assert_not_equals(ptr, NULL, ll_get_ref(ll, 0)); - cmc_assert_equals(int32_t, 4, total_read); - - cmc_assert(ll_contains(ll, 10)); - cmc_assert_equals(int32_t, 5, total_read); - - cmc_assert_equals(int32_t, 4, total_create); - cmc_assert_equals(int32_t, 5, total_read); - cmc_assert_equals(int32_t, 0, total_update); - cmc_assert_equals(int32_t, 3, total_delete); - cmc_assert_equals(int32_t, 0, total_resize); - - ll_customize(ll, NULL, NULL); - - cmc_assert_equals(ptr, NULL, ll->callbacks); - - ll_clear(ll); - cmc_assert(ll_push_front(ll, 10)); - cmc_assert(ll_push_back(ll, 10)); - cmc_assert(ll_push_at(ll, 10, 1)); - cmc_assert(ll_pop_at(ll, 1)); - cmc_assert(ll_pop_front(ll)); - cmc_assert(ll_pop_back(ll)); - cmc_assert(ll_push_back(ll, 10)); - cmc_assert_equals(size_t, 10, ll_front(ll)); - cmc_assert_equals(size_t, 10, ll_back(ll)); - cmc_assert_equals(size_t, 10, ll_get(ll, 0)); - cmc_assert_not_equals(ptr, NULL, ll_get_ref(ll, 0)); - cmc_assert(ll_contains(ll, 10)); - - cmc_assert_equals(int32_t, 4, total_create); - cmc_assert_equals(int32_t, 5, total_read); - cmc_assert_equals(int32_t, 0, total_update); - cmc_assert_equals(int32_t, 3, total_delete); - cmc_assert_equals(int32_t, 0, total_resize); - - cmc_assert_equals(ptr, NULL, ll->callbacks); - - ll_free(ll); - - total_create = 0; - total_read = 0; - total_update = 0; - total_delete = 0; - total_resize = 0; - }); -}); - -CMC_CREATE_UNIT(CMCLinkedListIter, true, { - CMC_CREATE_TEST(PFX##_iter_start(), { - struct linkedlist *ll = ll_new(ll_fval); - - cmc_assert_not_equals(ptr, NULL, ll); - - struct linkedlist_iter it = ll_iter_start(ll); - - cmc_assert_equals(ptr, ll, it.target); - cmc_assert_equals(ptr, NULL, it.cursor); - cmc_assert_equals(size_t, 0, it.index); - cmc_assert_equals(bool, true, it.start); - cmc_assert_equals(bool, true, it.end); - - cmc_assert(ll_iter_at_start(&it)); - cmc_assert(ll_iter_at_end(&it)); - - cmc_assert(ll_push_front(ll, 1)); - cmc_assert(ll_push_front(ll, 2)); - - it = ll_iter_start(ll); - - cmc_assert_equals(size_t, 0, it.index); - cmc_assert_equals(bool, false, it.end); - cmc_assert_equals(ptr, ll->head, it.cursor); - - ll_free(ll); - }); - - CMC_CREATE_TEST(PFX##_iter_end(), { - struct linkedlist *ll = ll_new(ll_fval); - - cmc_assert_not_equals(ptr, NULL, ll); - - struct linkedlist_iter it = ll_iter_end(ll); - - cmc_assert_equals(ptr, ll, it.target); - cmc_assert_equals(ptr, NULL, it.cursor); - cmc_assert_equals(size_t, 0, it.index); - cmc_assert_equals(bool, true, it.start); - cmc_assert_equals(bool, true, it.end); - - cmc_assert(ll_iter_at_start(&it)); - cmc_assert(ll_iter_at_end(&it)); - - cmc_assert(ll_push_back(ll, 1)); - cmc_assert(ll_push_back(ll, 2)); - cmc_assert(ll_push_back(ll, 3)); - - it = ll_iter_end(ll); - - cmc_assert_equals(size_t, ll->count - 1, it.index); - cmc_assert_equals(ptr, ll->tail, it.cursor); - cmc_assert_equals(bool, false, it.start); - - ll_free(ll); - }); - - CMC_CREATE_TEST(PFX##_iter_at_start(), { - struct linkedlist *ll = ll_new(ll_fval); - - cmc_assert_not_equals(ptr, NULL, ll); - - struct linkedlist_iter it = ll_iter_start(ll); - - // Empty checks - cmc_assert(ll_iter_at_start(&it)); - it = ll_iter_end(ll); - cmc_assert(ll_iter_at_start(&it)); - - // Non-empty checks - cmc_assert(ll_push_back(ll, 1)); - it = ll_iter_end(ll); - cmc_assert(!ll_iter_at_start(&it)); - it = ll_iter_start(ll); - cmc_assert(ll_iter_at_start(&it)); - - ll_clear(ll); - - cmc_assert(ll_push_front(ll, 1)); - it = ll_iter_end(ll); - cmc_assert(!ll_iter_at_start(&it)); - it = ll_iter_start(ll); - cmc_assert(ll_iter_at_start(&it)); - - ll_free(ll); - }); - - CMC_CREATE_TEST(PFX##_iter_at_end(), { - struct linkedlist *ll = ll_new(ll_fval); - - cmc_assert_not_equals(ptr, NULL, ll); - - struct linkedlist_iter it = ll_iter_start(ll); - - // Empty check - cmc_assert(ll_iter_at_end(&it)); - it = ll_iter_end(ll); - cmc_assert(ll_iter_at_end(&it)); - - // Non-empty checks - cmc_assert(ll_push_back(ll, 1)); - it = ll_iter_end(ll); - cmc_assert(ll_iter_at_end(&it)); - it = ll_iter_start(ll); - cmc_assert(!ll_iter_at_end(&it)); - - ll_clear(ll); - - cmc_assert(ll_push_front(ll, 1)); - it = ll_iter_end(ll); - cmc_assert(ll_iter_at_end(&it)); - it = ll_iter_start(ll); - cmc_assert(!ll_iter_at_end(&it)); - - ll_free(ll); - }); - - CMC_CREATE_TEST(PFX##_iter_to_start(), { - struct linkedlist *ll = ll_new(ll_fval); - - cmc_assert_not_equals(ptr, NULL, ll); - - struct linkedlist_iter it = ll_iter_start(ll); - - cmc_assert(!ll_iter_to_start(&it)); - - for (size_t i = 1; i <= 100; i++) - { - if (i % 2 == 0) - ll_push_back(ll, i); - else - ll_push_front(ll, i); - } - - cmc_assert_equals(size_t, 100, ll->count); - - it = ll_iter_end(ll); - - cmc_assert(!ll_iter_at_start(&it)); - cmc_assert(ll_iter_at_end(&it)); - - cmc_assert_equals(size_t, 100, ll_iter_value(&it)); - - cmc_assert(ll_iter_to_start(&it)); - - cmc_assert(ll_iter_at_start(&it)); - cmc_assert(!ll_iter_at_end(&it)); - - cmc_assert_equals(size_t, 99, ll_iter_value(&it)); - - ll_free(ll); - }); - - CMC_CREATE_TEST(PFX##_iter_to_end(), { - struct linkedlist *ll = ll_new(ll_fval); - - cmc_assert_not_equals(ptr, NULL, ll); - - struct linkedlist_iter it = ll_iter_end(ll); - - cmc_assert(!ll_iter_to_end(&it)); - - for (size_t i = 1; i <= 100; i++) - { - if (i % 2 == 0) - ll_push_back(ll, i); - else - ll_push_front(ll, i); - } - - it = ll_iter_start(ll); - - cmc_assert(ll_iter_at_start(&it)); - cmc_assert(!ll_iter_at_end(&it)); - - cmc_assert_equals(size_t, 99, ll_iter_value(&it)); - - cmc_assert(ll_iter_to_end(&it)); - - cmc_assert(!ll_iter_at_start(&it)); - cmc_assert(ll_iter_at_end(&it)); - - cmc_assert_equals(size_t, 100, ll_iter_value(&it)); - - ll_free(ll); - }); - - CMC_CREATE_TEST(PFX##_iter_next(), { - struct linkedlist *ll = ll_new(ll_fval); - - cmc_assert_not_equals(ptr, NULL, ll); - - struct linkedlist_iter it = ll_iter_start(ll); - - cmc_assert(!ll_iter_next(&it)); - - for (size_t i = 1; i <= 1000; i++) - { - if (i % 2 == 0) - ll_push_back(ll, i); - else - ll_push_front(ll, i); - } - - size_t sum = 0; - for (it = ll_iter_start(ll); !ll_iter_at_end(&it); ll_iter_next(&it)) - { - sum += ll_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - - ll_iter_to_start(&it); - do - { - sum += ll_iter_value(&it); - } while (ll_iter_next(&it)); - - cmc_assert_equals(size_t, 500500, sum); - - ll_free(ll); - }); - - CMC_CREATE_TEST(PFX##_iter_prev(), { - struct linkedlist *ll = ll_new(ll_fval); - - cmc_assert_not_equals(ptr, NULL, ll); - - struct linkedlist_iter it = ll_iter_end(ll); - - cmc_assert(!ll_iter_prev(&it)); - - for (size_t i = 1; i <= 1000; i++) - { - if (i % 2 == 0) - ll_push_back(ll, i); - else - ll_push_front(ll, i); - } - - size_t sum = 0; - for (it = ll_iter_end(ll); !ll_iter_at_start(&it); ll_iter_prev(&it)) - { - sum += ll_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - - ll_iter_to_end(&it); - do - { - sum += ll_iter_value(&it); - } while (ll_iter_prev(&it)); - - cmc_assert_equals(size_t, 500500, sum); - - ll_free(ll); - }); - - CMC_CREATE_TEST(PFX##_iter_advance(), { - struct linkedlist *ll = ll_new(ll_fval); - - cmc_assert_not_equals(ptr, NULL, ll); - - struct linkedlist_iter it = ll_iter_start(ll); - - cmc_assert(!ll_iter_advance(&it, 1)); - - for (size_t i = 0; i <= 1000; i++) - { - if (i % 2 == 0) - ll_push_back(ll, i); // will sum all even numbers - else - ll_push_back(ll, 0); - } - - it = ll_iter_start(ll); - - cmc_assert(!ll_iter_advance(&it, 0)); - cmc_assert(!ll_iter_advance(&it, ll->count)); - - size_t sum = 0; - for (it = ll_iter_start(ll);;) - { - sum += ll_iter_value(&it); - - if (!ll_iter_advance(&it, 2)) - break; - } - - cmc_assert_equals(size_t, 250500, sum); - - ll_iter_to_start(&it); - cmc_assert(ll_iter_advance(&it, ll->count - 1)); - - ll_free(ll); - }); - - CMC_CREATE_TEST(PFX##_iter_rewind(), { - struct linkedlist *ll = ll_new(ll_fval); - - cmc_assert_not_equals(ptr, NULL, ll); - - struct linkedlist_iter it = ll_iter_end(ll); - - cmc_assert(!ll_iter_rewind(&it, 1)); - - for (size_t i = 0; i <= 1000; i++) - { - if (i % 2 == 0) - ll_push_front(ll, i); // will sum all even numbers - else - ll_push_front(ll, 0); - } - - it = ll_iter_end(ll); - - cmc_assert(!ll_iter_rewind(&it, 0)); - cmc_assert(!ll_iter_rewind(&it, ll->count)); - - size_t sum = 0; - for (it = ll_iter_end(ll);;) - { - sum += ll_iter_value(&it); - - if (!ll_iter_rewind(&it, 2)) - break; - } - - cmc_assert_equals(size_t, 250500, sum); - - ll_iter_to_end(&it); - cmc_assert(ll_iter_rewind(&it, ll->count - 1)); - - ll_free(ll); - }); - - CMC_CREATE_TEST(PFX##_iter_go_to(), { - struct linkedlist *ll = ll_new(ll_fval); - - cmc_assert_not_equals(ptr, NULL, ll); - - struct linkedlist_iter it = ll_iter_end(ll); - cmc_assert(!ll_iter_go_to(&it, 0)); - - it = ll_iter_start(ll); - cmc_assert(!ll_iter_go_to(&it, 0)); - - for (size_t i = 0; i <= 1000; i++) - ll_push_back(ll, i); - - it = ll_iter_start(ll); - - size_t sum = 0; - for (size_t i = 0; i < 1001; i++) - { - ll_iter_go_to(&it, i); - - sum += ll_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - for (size_t i = 1001; i > 0; i--) - { - cmc_assert(ll_iter_go_to(&it, i - 1)); - - sum += ll_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - for (size_t i = 0; i < 1001; i += 100) - { - cmc_assert(ll_iter_go_to(&it, i)); - cmc_assert_equals(size_t, i, ll_iter_index(&it)); - - sum += ll_iter_value(&it); - } - - cmc_assert_equals(size_t, 5500, sum); - - ll_free(ll); - }); - - CMC_CREATE_TEST(PFX##_iter_value(), { - struct linkedlist *ll = ll_new(ll_fval); - - cmc_assert_not_equals(ptr, NULL, ll); - - struct linkedlist_iter it = ll_iter_end(ll); - - cmc_assert_equals(size_t, (size_t){ 0 }, ll_iter_value(&it)); - - cmc_assert(ll_push_back(ll, 10)); - - it = ll_iter_start(ll); - - cmc_assert_equals(size_t, 10, ll_iter_value(&it)); - - ll_free(ll); - }); - - CMC_CREATE_TEST(PFX##_iter_rvalue(), { - struct linkedlist *ll = ll_new(ll_fval); - - cmc_assert_not_equals(ptr, NULL, ll); - - struct linkedlist_iter it = ll_iter_end(ll); - - cmc_assert_equals(ptr, NULL, ll_iter_rvalue(&it)); - - cmc_assert(ll_push_back(ll, 10)); - - it = ll_iter_start(ll); - - cmc_assert_not_equals(ptr, NULL, ll_iter_rvalue(&it)); - cmc_assert_equals(size_t, 10, *ll_iter_rvalue(&it)); - - ll_free(ll); - }); - - CMC_CREATE_TEST(PFX##_iter_index(), { - struct linkedlist *ll = ll_new(ll_fval); - - cmc_assert_not_equals(ptr, NULL, ll); - - for (size_t i = 0; i <= 1000; i++) - ll_push_back(ll, i); - - struct linkedlist_iter it = ll_iter_start(ll); - - for (size_t i = 0; i < 1001; i++) - { - cmc_assert_equals(size_t, i, ll_iter_index(&it)); - ll_iter_next(&it); - } - - it = ll_iter_end(ll); - for (size_t i = 1001; i > 0; i--) - { - cmc_assert_equals(size_t, i - 1, ll_iter_index(&it)); - ll_iter_prev(&it); - } - - ll_free(ll); - }); -}); - -#ifdef CMC_TEST_MAIN -int main(void) -{ - int result = CMCLinkedList() + CMCLinkedListIter(); - - printf(" +---------------------------------------------------------------+"); - printf("\n"); - printf(" | CMCLinkedList Suit : %-43s |\n", result == 0 ? "PASSED" : "FAILED"); - printf(" +---------------------------------------------------------------+"); - printf("\n\n\n"); - - return result; -} -#endif - -#endif /* CMC_TESTS_UNT_CMC_INKEDLIST_H */ diff --git a/tests/unt/unt_cmc_list.h b/tests/unt/unt_cmc_list.h deleted file mode 100644 index 46cf216..0000000 --- a/tests/unt/unt_cmc_list.h +++ /dev/null @@ -1,1081 +0,0 @@ -#ifndef CMC_TESTS_UNT_CMC_LIST_H -#define CMC_TESTS_UNT_CMC_LIST_H - -#include "utl.h" - -#include "tst_cmc_list.h" - -struct list_fval *l_fval = &(struct list_fval){ - .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp -}; - -CMC_CREATE_UNIT(CMCList, true, { - CMC_CREATE_TEST(new, { - struct list *l = l_new(1000000, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - cmc_assert_not_equals(ptr, NULL, l->buffer); - cmc_assert_equals(size_t, 1000000, l_capacity(l)); - cmc_assert_equals(size_t, 0, l_count(l)); - - l_free(l); - }); - - CMC_CREATE_TEST(new[capacity = 0], { - struct list *l = l_new(0, l_fval); - - cmc_assert_equals(ptr, NULL, l); - }); - - CMC_CREATE_TEST(new[capacity = UINT64_MAX], { - struct list *l = l_new(UINT64_MAX, l_fval); - - cmc_assert_equals(ptr, NULL, l); - }); - - CMC_CREATE_TEST(clear[count capacity], { - struct list *l = l_new(100, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - - for (size_t i = 0; i < 50; i++) - l_push_back(l, i); - - cmc_assert_equals(size_t, 50, l_count(l)); - - l_clear(l); - - cmc_assert_equals(size_t, 0, l_count(l)); - cmc_assert_equals(size_t, 100, l_capacity(l)); - - l_free(l); - }); - - CMC_CREATE_TEST(buffer_growth[capacity = 1], { - struct list *l = l_new(1, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - - for (size_t i = 0; i < 100; i++) - l_push_back(l, i); - - cmc_assert_equals(size_t, 100, l_count(l)); - - for (size_t i = 0; i < 100; i++) - cmc_assert_equals(size_t, i, l_get(l, i)); - - l_free(l); - }); - - CMC_CREATE_TEST(push_front[count], { - struct list *l = l_new(100, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - - for (size_t i = 0; i < 250; i++) - cmc_assert(l_push_front(l, i)); - - cmc_assert_equals(size_t, 250, l_count(l)); - - l_free(l); - }); - - CMC_CREATE_TEST(push_front[capacity], { - struct list *l = l_new(100, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - - for (size_t i = 0; i < 250; i++) - cmc_assert(l_push_front(l, i)); - - cmc_assert_lesser_equals(size_t, l_capacity(l), l_count(l)); - - l_free(l); - }); - - CMC_CREATE_TEST(push_front[item preservation], { - struct list *l = l_new(100, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - - for (size_t i = 0; i < 250; i++) - cmc_assert(l_push_front(l, i)); - - for (size_t i = 0; i < l_count(l); i++) - cmc_assert_equals(size_t, l_get(l, i), l_count(l) - i - 1); - - l_free(l); - }); - - CMC_CREATE_TEST(push_at[count], { - struct list *l = l_new(100, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - - cmc_assert(l_push_back(l, 0)); - cmc_assert(l_push_back(l, 249)); - - for (size_t i = 1; i < 249; i++) - cmc_assert(l_push_at(l, i, l_count(l) - 1)); - - cmc_assert_equals(size_t, 250, l_count(l)); - - l_free(l); - }); - - CMC_CREATE_TEST(push_at[capacity], { - struct list *l = l_new(100, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - - cmc_assert(l_push_back(l, 0)); - cmc_assert(l_push_back(l, 249)); - - for (size_t i = 1; i < 249; i++) - cmc_assert(l_push_at(l, i, l_count(l) - 1)); - - cmc_assert_lesser_equals(size_t, l_capacity(l), l_count(l)); - - l_free(l); - }); - - CMC_CREATE_TEST(push_at[item preservation], { - struct list *l = l_new(100, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - - cmc_assert(l_push_back(l, 0)); - cmc_assert(l_push_back(l, 249)); - - for (size_t i = 1; i < 249; i++) - cmc_assert(l_push_at(l, i, l_count(l) - 1)); - - for (size_t i = 0; i < l_count(l); i++) - cmc_assert_equals(size_t, l_get(l, i), i); - - l_free(l); - }); - - CMC_CREATE_TEST(push_back[count], { - struct list *l = l_new(100, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - - for (size_t i = 0; i < 250; i++) - cmc_assert(l_push_back(l, i)); - - cmc_assert_equals(size_t, 250, l_count(l)); - - l_free(l); - }); - - CMC_CREATE_TEST(push_back[capacity], { - struct list *l = l_new(100, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - - for (size_t i = 0; i < 250; i++) - cmc_assert(l_push_back(l, i)); - - cmc_assert_lesser_equals(size_t, l_capacity(l), l_count(l)); - - l_free(l); - }); - - CMC_CREATE_TEST(push_back[item preservation], { - struct list *l = l_new(100, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - - for (size_t i = 0; i < 250; i++) - cmc_assert(l_push_back(l, i)); - - for (size_t i = 0; i < l_count(l); i++) - cmc_assert_equals(size_t, l_get(l, i), i); - - l_free(l); - }); - - CMC_CREATE_TEST(pop_front[count], { - struct list *l = l_new(100, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - - for (size_t i = 0; i < 250; i++) - l_push_back(l, i); - - cmc_assert(l_pop_front(l)); - - l_free(l); - }); - - CMC_CREATE_TEST(pop_front[item preservation], { - struct list *l = l_new(100, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - - for (size_t i = 0; i < 250; i++) - l_push_back(l, i); - - cmc_assert(l_pop_front(l)); - - for (size_t i = 0; i < l_count(l); i++) - cmc_assert_equals(size_t, l_get(l, i), i + 1); - - l_free(l); - }); - - CMC_CREATE_TEST(pop_front[count = 0], { - struct list *l = l_new(100, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - cmc_assert(!l_pop_front(l)); - - l_free(l); - }); - - CMC_CREATE_TEST(pop_front[count = 1], { - struct list *l = l_new(100, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - cmc_assert(l_push_back(l, 10)); - cmc_assert(l_pop_front(l)); - - l_free(l); - }); - - CMC_CREATE_TEST(pop_front[buffer_clear], { - struct list *l = l_new(100, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - cmc_assert(l_push_back(l, 1)); - cmc_assert(l_push_front(l, 2)); - - cmc_assert(l_pop_front(l)); - - cmc_assert_equals(size_t, 0, l->buffer[1]); - - l_free(l); - }); - - CMC_CREATE_TEST(pop_at[count = 0], { - struct list *l = l_new(100, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - cmc_assert(!l_pop_at(l, 1)); - - l_free(l); - }); - - CMC_CREATE_TEST(pop_at[count = 1], { - struct list *l = l_new(100, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - cmc_assert(l_push_back(l, 1)); - cmc_assert(l_pop_at(l, 0)); - - cmc_assert_equals(size_t, 0, l->buffer[0]); - - l_free(l); - }); - - CMC_CREATE_TEST(pop_at[buffer_clear], { - struct list *l = l_new(100, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - cmc_assert(l_push_back(l, 1)); - cmc_assert(l_push_back(l, 2)); - cmc_assert(l_push_back(l, 3)); - cmc_assert(l_pop_at(l, 1)); - - l_free(l); - }); - - CMC_CREATE_TEST(pop_back[count = 0], { - struct list *l = l_new(100, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - cmc_assert(!l_pop_back(l)); - - l_free(l); - }); - - CMC_CREATE_TEST(pop_back[count = 1], { - struct list *l = l_new(100, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - cmc_assert(l_push_back(l, 10)); - cmc_assert(l_pop_back(l)); - - l_free(l); - }); - - CMC_CREATE_TEST(flags, { - struct list *l = l_new(100, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); - - // clear - l->flag = CMC_FLAG_ERROR; - l_clear(l); - cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); - - // customize - l->flag = CMC_FLAG_ERROR; - l_customize(l, NULL, NULL); - cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); - - // push_front - l->flag = CMC_FLAG_ERROR; - cmc_assert(l_push_front(l, 10)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); - - // push_at - cmc_assert(!l_push_at(l, 5, 2)); - cmc_assert_equals(int32_t, CMC_FLAG_RANGE, l_flag(l)); - cmc_assert(l_push_at(l, 5, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); - - // push_back - l->flag = CMC_FLAG_ERROR; - cmc_assert(l_push_back(l, 0)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); - - // pop_front - l->flag = CMC_FLAG_ERROR; - cmc_assert(l_pop_front(l)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); - - l_clear(l); - cmc_assert(!l_pop_front(l)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, l_flag(l)); - - // pop_back - cmc_assert(l_push_front(l, 10)); - l->flag = CMC_FLAG_ERROR; - cmc_assert(l_pop_back(l)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); - - cmc_assert(!l_pop_front(l)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, l_flag(l)); - - // pop_at - l->flag = CMC_FLAG_ERROR; - cmc_assert(!l_pop_at(l, 0)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, l_flag(l)); - - cmc_assert(l_push_back(l, 10)); - cmc_assert(!l_pop_at(l, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_RANGE, l_flag(l)); - - cmc_assert(l_pop_at(l, 0)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); - - // seq_push_front - cmc_assert(!l_seq_push_front(l, NULL, 0)); - cmc_assert_equals(int32_t, CMC_FLAG_INVALID, l_flag(l)); - - cmc_assert(l_seq_push_front(l, (size_t[2]){ 1, 2 }, 2)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); - - // seq_push_at - cmc_assert(!l_seq_push_at(l, NULL, 0, 0)); - cmc_assert_equals(int32_t, CMC_FLAG_INVALID, l_flag(l)); - - cmc_assert(!l_seq_push_at(l, (size_t[2]){ 1, 2 }, 2, 10)); - cmc_assert_equals(int32_t, CMC_FLAG_RANGE, l_flag(l)); - - cmc_assert(l_seq_push_at(l, (size_t[2]){ 1, 2 }, 2, l_count(l) - 1)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); - - // seq_push_back - cmc_assert(!l_seq_push_back(l, NULL, 0)); - cmc_assert_equals(int32_t, CMC_FLAG_INVALID, l_flag(l)); - - cmc_assert(l_seq_push_back(l, (size_t[2]){ 1, 2 }, 2)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); - - // seq_pop_at - cmc_assert(!l_seq_pop_at(l, 10, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_INVALID, l_flag(l)); - - cmc_assert(!l_seq_pop_at(l, 100, 200)); - cmc_assert_equals(int32_t, CMC_FLAG_RANGE, l_flag(l)); - - cmc_assert(l_seq_pop_at(l, 1, l_count(l) - 2)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); - - // seq_sublist - struct list *l2 = l_seq_sublist(l, 10, 1); - cmc_assert_equals(ptr, NULL, l2); - cmc_assert_equals(int32_t, CMC_FLAG_INVALID, l_flag(l)); - - l2 = l_seq_sublist(l, 100, 200); - cmc_assert_equals(ptr, NULL, l2); - cmc_assert_equals(int32_t, CMC_FLAG_RANGE, l_flag(l)); - - l2 = l_seq_sublist(l, 0, l_count(l) - 1); - cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l2)); - - l_clear(l); - - // l_front - l_front(l); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, l_flag(l)); - - cmc_assert(l_push_back(l, 10)); - l->flag = CMC_FLAG_ERROR; - l_front(l); - cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); - - l_clear(l); - - // l_back - l_back(l); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, l_flag(l)); - - cmc_assert(l_push_back(l, 10)); - l->flag = CMC_FLAG_ERROR; - l_back(l); - cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); - - l_clear(l); - - // get, get_ref - l_get(l, 0); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, l_flag(l)); - l->flag = CMC_FLAG_ERROR; - l_get_ref(l, 0); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, l_flag(l)); - - cmc_assert(l_push_back(l, 10)); - - l_get(l, 1); - cmc_assert_equals(int32_t, CMC_FLAG_RANGE, l_flag(l)); - l->flag = CMC_FLAG_ERROR; - l_get_ref(l, 1); - cmc_assert_equals(int32_t, CMC_FLAG_RANGE, l_flag(l)); - - l_get(l, 0); - cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); - l->flag = CMC_FLAG_ERROR; - l_get_ref(l, 0); - cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); - - // index_of - l->flag = CMC_FLAG_ERROR; - l_index_of(l, 10, false); - cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); - - // contains - l->flag = CMC_FLAG_ERROR; - cmc_assert(l_contains(l, 10)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); - - // copy_of - l->flag = CMC_FLAG_ERROR; - struct list *l3 = l_copy_of(l); - cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l3)); - - // equals - l->flag = CMC_FLAG_ERROR; - l3->flag = CMC_FLAG_ERROR; - cmc_assert(l_equals(l, l3)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l3)); - - l_free(l); - l_free(l2); - l_free(l3); - }); - - CMC_CREATE_TEST(callbacks, { - struct list *l = l_new_custom(100, l_fval, NULL, callbacks); - - cmc_assert_not_equals(ptr, NULL, l); - - total_create = 0; - total_read = 0; - total_update = 0; - total_delete = 0; - total_resize = 0; - - cmc_assert(l_push_front(l, 10)); - cmc_assert_equals(int32_t, 1, total_create); - - cmc_assert(l_push_back(l, 10)); - cmc_assert_equals(int32_t, 2, total_create); - - cmc_assert(l_push_at(l, 10, 1)); - cmc_assert_equals(int32_t, 3, total_create); - - cmc_assert(l_pop_at(l, 1)); - cmc_assert_equals(int32_t, 1, total_delete); - - cmc_assert(l_pop_front(l)); - cmc_assert_equals(int32_t, 2, total_delete); - - cmc_assert(l_pop_back(l)); - cmc_assert_equals(int32_t, 3, total_delete); - - cmc_assert(l_push_back(l, 10)); - cmc_assert_equals(int32_t, 4, total_create); - - cmc_assert_equals(size_t, 10, l_front(l)); - cmc_assert_equals(int32_t, 1, total_read); - - cmc_assert_equals(size_t, 10, l_back(l)); - cmc_assert_equals(int32_t, 2, total_read); - - cmc_assert_equals(size_t, 10, l_get(l, 0)); - cmc_assert_equals(int32_t, 3, total_read); - - cmc_assert_not_equals(ptr, NULL, l_get_ref(l, 0)); - cmc_assert_equals(int32_t, 4, total_read); - - cmc_assert(l_contains(l, 10)); - cmc_assert_equals(int32_t, 5, total_read); - - cmc_assert(l_seq_push_front(l, (size_t[]){ 7, 8, 9 }, 3)); - cmc_assert_equals(int32_t, 5, total_create); - - cmc_assert(l_seq_push_back(l, (size_t[]){ 14, 15, 16 }, 3)); - cmc_assert_equals(int32_t, 6, total_create); - - cmc_assert(l_seq_push_at(l, (size_t[]){ 11, 12, 13 }, 3, 4)); - cmc_assert_equals(int32_t, 7, total_create); - - cmc_assert(l_seq_pop_at(l, 1, 4)); - cmc_assert_equals(int32_t, 4, total_delete); - - struct list *l2 = l_seq_sublist(l, 0, 4); - cmc_assert_equals(int32_t, 5, total_delete); - - cmc_assert(l_resize(l, 1000)); - cmc_assert_equals(int32_t, 1, total_resize); - - cmc_assert(l_resize(l2, 1000)); - cmc_assert_equals(int32_t, 2, total_resize); - - cmc_assert_equals(int32_t, 7, total_create); - cmc_assert_equals(int32_t, 5, total_read); - cmc_assert_equals(int32_t, 0, total_update); - cmc_assert_equals(int32_t, 5, total_delete); - cmc_assert_equals(int32_t, 2, total_resize); - - l_customize(l, NULL, NULL); - - cmc_assert_equals(ptr, NULL, l->callbacks); - - l_clear(l); - cmc_assert(l_push_front(l, 10)); - cmc_assert(l_push_back(l, 10)); - cmc_assert(l_push_at(l, 10, 1)); - cmc_assert(l_pop_at(l, 1)); - cmc_assert(l_pop_front(l)); - cmc_assert(l_pop_back(l)); - cmc_assert(l_push_back(l, 10)); - cmc_assert_equals(size_t, 10, l_front(l)); - cmc_assert_equals(size_t, 10, l_back(l)); - cmc_assert_equals(size_t, 10, l_get(l, 0)); - cmc_assert_not_equals(ptr, NULL, l_get_ref(l, 0)); - cmc_assert(l_contains(l, 10)); - cmc_assert(l_seq_push_front(l, (size_t[]){ 7, 8, 9 }, 3)); - cmc_assert(l_seq_push_back(l, (size_t[]){ 14, 15, 16 }, 3)); - cmc_assert(l_seq_push_at(l, (size_t[]){ 11, 12, 13 }, 3, 4)); - cmc_assert(l_seq_pop_at(l, 1, 4)); - struct list *l3 = l_seq_sublist(l, 0, 4); - cmc_assert(l_resize(l, 1000)); - cmc_assert(l_resize(l3, 1000)); - - cmc_assert_equals(int32_t, 7, total_create); - cmc_assert_equals(int32_t, 5, total_read); - cmc_assert_equals(int32_t, 0, total_update); - cmc_assert_equals(int32_t, 5, total_delete); - cmc_assert_equals(int32_t, 2, total_resize); - - cmc_assert_equals(ptr, NULL, l->callbacks); - - l_free(l); - l_free(l2); - l_free(l3); - - total_create = 0; - total_read = 0; - total_update = 0; - total_delete = 0; - total_resize = 0; - }); -}) - -CMC_CREATE_UNIT(CMCListIter, true, { - CMC_CREATE_TEST(PFX##_iter_start(), { - struct list *l = l_new(100, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - - struct list_iter it = l_iter_start(l); - - cmc_assert_equals(ptr, l, it.target); - cmc_assert_equals(size_t, 0, it.cursor); - cmc_assert_equals(bool, true, it.start); - cmc_assert_equals(bool, true, it.end); - - cmc_assert(l_iter_at_start(&it)); - cmc_assert(l_iter_at_end(&it)); - - cmc_assert(l_push_front(l, 1)); - cmc_assert(l_push_front(l, 2)); - - it = l_iter_start(l); - - cmc_assert_equals(size_t, 0, it.cursor); - cmc_assert_equals(bool, false, it.end); - - l_free(l); - }); - - CMC_CREATE_TEST(PFX##_iter_end(), { - struct list *l = l_new(100, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - - struct list_iter it = l_iter_end(l); - - cmc_assert_equals(ptr, l, it.target); - cmc_assert_equals(size_t, 0, it.cursor); - cmc_assert_equals(bool, true, it.start); - cmc_assert_equals(bool, true, it.end); - - cmc_assert(l_iter_at_start(&it)); - cmc_assert(l_iter_at_end(&it)); - - cmc_assert(l_push_back(l, 1)); - cmc_assert(l_push_back(l, 2)); - cmc_assert(l_push_back(l, 3)); - - it = l_iter_end(l); - - cmc_assert_equals(size_t, l->count - 1, it.cursor); - cmc_assert_equals(bool, false, it.start); - - l_free(l); - }); - - CMC_CREATE_TEST(PFX##_iter_at_start(), { - struct list *l = l_new(100, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - - struct list_iter it = l_iter_start(l); - - // Empty checks - cmc_assert(l_iter_at_start(&it)); - it = l_iter_end(l); - cmc_assert(l_iter_at_start(&it)); - - // Non-empty checks - cmc_assert(l_push_back(l, 1)); - it = l_iter_end(l); - cmc_assert(!l_iter_at_start(&it)); - it = l_iter_start(l); - cmc_assert(l_iter_at_start(&it)); - - l_clear(l); - - cmc_assert(l_push_front(l, 1)); - it = l_iter_end(l); - cmc_assert(!l_iter_at_start(&it)); - it = l_iter_start(l); - cmc_assert(l_iter_at_start(&it)); - - l_free(l); - }); - - CMC_CREATE_TEST(PFX##_iter_at_end(), { - struct list *l = l_new(100, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - - struct list_iter it = l_iter_start(l); - - // Empty check - cmc_assert(l_iter_at_end(&it)); - it = l_iter_end(l); - cmc_assert(l_iter_at_end(&it)); - - // Non-empty checks - cmc_assert(l_push_back(l, 1)); - it = l_iter_end(l); - cmc_assert(l_iter_at_end(&it)); - it = l_iter_start(l); - cmc_assert(!l_iter_at_end(&it)); - - l_clear(l); - - cmc_assert(l_push_front(l, 1)); - it = l_iter_end(l); - cmc_assert(l_iter_at_end(&it)); - it = l_iter_start(l); - cmc_assert(!l_iter_at_end(&it)); - - l_free(l); - }); - - CMC_CREATE_TEST(PFX##_iter_to_start(), { - struct list *l = l_new(100, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - - struct list_iter it = l_iter_start(l); - - cmc_assert(!l_iter_to_start(&it)); - - for (size_t i = 1; i <= 100; i++) - { - if (i % 2 == 0) - l_push_back(l, i); - else - l_push_front(l, i); - } - - cmc_assert_equals(size_t, 100, l->count); - - it = l_iter_end(l); - - cmc_assert(!l_iter_at_start(&it)); - cmc_assert(l_iter_at_end(&it)); - - cmc_assert_equals(size_t, 100, l_iter_value(&it)); - - cmc_assert(l_iter_to_start(&it)); - - cmc_assert(l_iter_at_start(&it)); - cmc_assert(!l_iter_at_end(&it)); - - cmc_assert_equals(size_t, 99, l_iter_value(&it)); - - l_free(l); - }); - - CMC_CREATE_TEST(PFX##_iter_to_end(), { - struct list *l = l_new(100, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - - struct list_iter it = l_iter_end(l); - - cmc_assert(!l_iter_to_end(&it)); - - for (size_t i = 1; i <= 100; i++) - { - if (i % 2 == 0) - l_push_back(l, i); - else - l_push_front(l, i); - } - - it = l_iter_start(l); - - cmc_assert(l_iter_at_start(&it)); - cmc_assert(!l_iter_at_end(&it)); - - cmc_assert_equals(size_t, 99, l_iter_value(&it)); - - cmc_assert(l_iter_to_end(&it)); - - cmc_assert(!l_iter_at_start(&it)); - cmc_assert(l_iter_at_end(&it)); - - cmc_assert_equals(size_t, 100, l_iter_value(&it)); - - l_free(l); - }); - - CMC_CREATE_TEST(PFX##_iter_next(), { - struct list *l = l_new(100, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - - struct list_iter it = l_iter_start(l); - - cmc_assert(!l_iter_next(&it)); - - for (size_t i = 1; i <= 1000; i++) - { - if (i % 2 == 0) - l_push_back(l, i); - else - l_push_front(l, i); - } - - size_t sum = 0; - for (it = l_iter_start(l); !l_iter_at_end(&it); l_iter_next(&it)) - { - sum += l_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - - l_iter_to_start(&it); - do - { - sum += l_iter_value(&it); - } while (l_iter_next(&it)); - - cmc_assert_equals(size_t, 500500, sum); - - l_free(l); - }); - - CMC_CREATE_TEST(PFX##_iter_prev(), { - struct list *l = l_new(100, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - - struct list_iter it = l_iter_end(l); - - cmc_assert(!l_iter_prev(&it)); - - for (size_t i = 1; i <= 1000; i++) - { - if (i % 2 == 0) - l_push_back(l, i); - else - l_push_front(l, i); - } - - size_t sum = 0; - for (it = l_iter_end(l); !l_iter_at_start(&it); l_iter_prev(&it)) - { - sum += l_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - - l_iter_to_end(&it); - do - { - sum += l_iter_value(&it); - } while (l_iter_prev(&it)); - - cmc_assert_equals(size_t, 500500, sum); - - l_free(l); - }); - - CMC_CREATE_TEST(PFX##_iter_advance(), { - struct list *l = l_new(100, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - - struct list_iter it = l_iter_start(l); - - cmc_assert(!l_iter_advance(&it, 1)); - - for (size_t i = 0; i <= 1000; i++) - { - if (i % 2 == 0) - l_push_back(l, i); // will sum all even numbers - else - l_push_back(l, 0); - } - - it = l_iter_start(l); - - cmc_assert(!l_iter_advance(&it, 0)); - cmc_assert(!l_iter_advance(&it, l->count)); - - size_t sum = 0; - for (it = l_iter_start(l);;) - { - sum += l_iter_value(&it); - - if (!l_iter_advance(&it, 2)) - break; - } - - cmc_assert_equals(size_t, 250500, sum); - - l_iter_to_start(&it); - cmc_assert(l_iter_advance(&it, l->count - 1)); - - l_free(l); - }); - - CMC_CREATE_TEST(PFX##_iter_rewind(), { - struct list *l = l_new(100, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - - struct list_iter it = l_iter_end(l); - - cmc_assert(!l_iter_rewind(&it, 1)); - - for (size_t i = 0; i <= 1000; i++) - { - if (i % 2 == 0) - l_push_front(l, i); // will sum all even numbers - else - l_push_front(l, 0); - } - - it = l_iter_end(l); - - cmc_assert(!l_iter_rewind(&it, 0)); - cmc_assert(!l_iter_rewind(&it, l->count)); - - size_t sum = 0; - for (it = l_iter_end(l);;) - { - sum += l_iter_value(&it); - - if (!l_iter_rewind(&it, 2)) - break; - } - - cmc_assert_equals(size_t, 250500, sum); - - l_iter_to_end(&it); - cmc_assert(l_iter_rewind(&it, l->count - 1)); - - l_free(l); - }); - - CMC_CREATE_TEST(PFX##_iter_go_to(), { - struct list *l = l_new(100, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - - struct list_iter it = l_iter_end(l); - cmc_assert(!l_iter_go_to(&it, 0)); - - it = l_iter_start(l); - cmc_assert(!l_iter_go_to(&it, 0)); - - for (size_t i = 0; i <= 1000; i++) - l_push_back(l, i); - - it = l_iter_start(l); - - size_t sum = 0; - for (size_t i = 0; i < 1001; i++) - { - l_iter_go_to(&it, i); - - sum += l_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - for (size_t i = 1001; i > 0; i--) - { - cmc_assert(l_iter_go_to(&it, i - 1)); - - sum += l_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - for (size_t i = 0; i < 1001; i += 100) - { - cmc_assert(l_iter_go_to(&it, i)); - cmc_assert_equals(size_t, i, l_iter_index(&it)); - - sum += l_iter_value(&it); - } - - cmc_assert_equals(size_t, 5500, sum); - - l_free(l); - }); - - CMC_CREATE_TEST(PFX##_iter_value(), { - struct list *l = l_new(100, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - - struct list_iter it = l_iter_end(l); - - cmc_assert_equals(size_t, (size_t){ 0 }, l_iter_value(&it)); - - cmc_assert(l_push_back(l, 10)); - - it = l_iter_start(l); - - cmc_assert_equals(size_t, 10, l_iter_value(&it)); - - l_free(l); - }); - - CMC_CREATE_TEST(PFX##_iter_rvalue(), { - struct list *l = l_new(100, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - - struct list_iter it = l_iter_end(l); - - cmc_assert_equals(ptr, NULL, l_iter_rvalue(&it)); - - cmc_assert(l_push_back(l, 10)); - - it = l_iter_start(l); - - cmc_assert_not_equals(ptr, NULL, l_iter_rvalue(&it)); - cmc_assert_equals(size_t, 10, *l_iter_rvalue(&it)); - - l_free(l); - }); - - CMC_CREATE_TEST(PFX##_iter_index(), { - struct list *l = l_new(100, l_fval); - - cmc_assert_not_equals(ptr, NULL, l); - - for (size_t i = 0; i <= 1000; i++) - l_push_back(l, i); - - struct list_iter it = l_iter_start(l); - - for (size_t i = 0; i < 1001; i++) - { - cmc_assert_equals(size_t, i, l_iter_index(&it)); - l_iter_next(&it); - } - - it = l_iter_end(l); - for (size_t i = 1001; i > 0; i--) - { - cmc_assert_equals(size_t, i - 1, l_iter_index(&it)); - l_iter_prev(&it); - } - - l_free(l); - }); -}); - -#ifdef CMC_TEST_MAIN -int main(void) -{ - int result = CMCList() + CMCListIter(); - - printf(" +---------------------------------------------------------------+"); - printf("\n"); - printf(" | CMCList Suit : %-49s |\n", result == 0 ? "PASSED" : "FAILED"); - printf(" +---------------------------------------------------------------+"); - printf("\n\n\n"); - - return result; -} -#endif - -#endif /* CMC_TESTS_UNT_CMC_LIST_H */ diff --git a/tests/unt/unt_cmc_queue.h b/tests/unt/unt_cmc_queue.h deleted file mode 100644 index 77f5117..0000000 --- a/tests/unt/unt_cmc_queue.h +++ /dev/null @@ -1,967 +0,0 @@ -#ifndef CMC_TESTS_UNT_CMC_QUEUE_H -#define CMC_TESTS_UNT_CMC_QUEUE_H - -#include "utl.h" - -#include "tst_cmc_queue.h" - -struct queue_fval *q_fval = &(struct queue_fval){ - .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp -}; - -CMC_CREATE_UNIT(CMCQueue, true, { - CMC_CREATE_TEST(new, { - struct queue *q = q_new(1000000, q_fval); - - cmc_assert_not_equals(ptr, NULL, q); - 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); - - q_free(q); - }); - - CMC_CREATE_TEST(new[capacity = 0], { - struct queue *q = q_new(0, q_fval); - - cmc_assert_equals(ptr, NULL, q); - }); - - CMC_CREATE_TEST(new[capacity = UINT64_MAX], { - struct queue *q = q_new(UINT64_MAX, q_fval); - - cmc_assert_equals(ptr, NULL, q); - }); - - CMC_CREATE_TEST(clear[count capacity], { - struct queue *q = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q); - - for (size_t i = 0; i < 50; i++) - cmc_assert(q_enqueue(q, i)); - - cmc_assert_equals(size_t, 50, q_count(q)); - - q_clear(q); - - cmc_assert_equals(size_t, 0, q_count(q)); - cmc_assert_equals(size_t, 100, q_capacity(q)); - - q_free(q); - }); - - CMC_CREATE_TEST(buffer_growth[capacity = 1], { - struct queue *q = q_new(1, q_fval); - - cmc_assert_not_equals(ptr, NULL, q); - - for (size_t i = 0; i < 50; i++) - cmc_assert(q_enqueue(q, i)); - - cmc_assert_equals(size_t, 50, q_count(q)); - - q_free(q); - }); - - CMC_CREATE_TEST(buffer_growth[item preservation], { - struct queue *q = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q); - - for (size_t i = 1; i <= 1200; i++) - { - q_enqueue(q, i); - } - - size_t sum = 0; - for (size_t i = q->front, j = 0; j < q->count; i = (i + 1) % q->capacity, j++) - sum += q->buffer[i]; - - cmc_assert_equals(size_t, 1200, q_count(q)); - cmc_assert_equals(size_t, 720600, sum); - - q_free(q); - }); - - CMC_CREATE_TEST(enqueue[count capacity], { - struct queue *q = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q); - - for (size_t i = 0; i < 150; i++) - cmc_assert(q_enqueue(q, i)); - - cmc_assert_equals(size_t, 150, q_count(q)); - cmc_assert_greater(size_t, 100, q_capacity(q)); - - q_free(q); - }); - - CMC_CREATE_TEST(enqueue[item preservation], { - struct queue *q = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q); - - for (size_t i = 1; i <= 100; i++) - cmc_assert(q_enqueue(q, i)); - - size_t sum = 0; - - for (size_t i = q->front, j = 0; j < q->count; i = (i + 1) % q->capacity, j++) - { - sum += q->buffer[i]; - } - - cmc_assert_equals(size_t, 5050, sum); - - q_free(q); - }); - - CMC_CREATE_TEST(dequeue[count capacity], { - struct queue *q = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q); - - cmc_assert(q_enqueue(q, 10)); - cmc_assert(q_dequeue(q)); - - cmc_assert_equals(size_t, 0, q_count(q)); - - cmc_assert(q_enqueue(q, 10)); - cmc_assert(q_dequeue(q)); - - cmc_assert_equals(size_t, 0, q_count(q)); - - q_free(q); - }); - - CMC_CREATE_TEST(dequeue[item preservation], { - struct queue *q = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q); - - for (size_t i = 200; i > 0; i--) - cmc_assert(q_enqueue(q, i)); - - for (size_t i = 0; i < 100; i++) - cmc_assert(q_dequeue(q)); - - size_t sum = 0; - - for (size_t i = q->front, j = 0; j < q->count; i = (i + 1) % q->capacity, j++) - { - sum += q->buffer[i]; - } - - cmc_assert_equals(size_t, 5050, sum); - - q_free(q); - }); - - CMC_CREATE_TEST(peek[count = 0], { - struct queue *q = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q); - - size_t r = q_peek(q); - - cmc_assert_equals(size_t, (size_t){ 0 }, r); - - q_free(q); - }); - - CMC_CREATE_TEST(peek[sum], { - struct queue *q = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q); - - size_t sum = 0; - - for (size_t i = 0; i <= 100; i++) - cmc_assert(q_enqueue(q, i)); - - while (!q_empty(q)) - { - size_t r = q_peek(q); - - sum += r; - - cmc_assert(q_dequeue(q)); - } - - cmc_assert_equals(size_t, 5050, sum); - - q_free(q); - }); - - CMC_CREATE_TEST(contains, { - struct queue *q = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q); - - for (size_t i = 1; i <= 20; i++) - cmc_assert(q_enqueue(q, i)); - - for (size_t i = 1; i <= 20; i++) - cmc_assert(q_contains(q, i)); - - q_clear(q); - - for (size_t i = 1; i <= 20; i++) - cmc_assert(!q_contains(q, i)); - - q_free(q); - }); - - CMC_CREATE_TEST(contains[count = 0], { - struct queue *q = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q); - - cmc_assert(!q_contains(q, 10)); - - q_free(q); - }); - - CMC_CREATE_TEST(contains[count = 1], { - struct queue *q = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q); - - cmc_assert(!q_contains(q, 10)); - - cmc_assert(q_enqueue(q, 100)); - - cmc_assert(q_contains(q, 100)); - cmc_assert(!q_contains(q, 101)); - - q_free(q); - }); - - CMC_CREATE_TEST(empty, { - struct queue *q = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q); - - cmc_assert(q_empty(q)); - - cmc_assert(q_enqueue(q, 1)); - - cmc_assert(!q_empty(q)); - - q_free(q); - }); - - CMC_CREATE_TEST(full, { - struct queue *q = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q); - - cmc_assert(!q_full(q)); - - for (size_t i = 0; i != q_capacity(q); i++) - cmc_assert(q_enqueue(q, i)); - - cmc_assert(q_full(q)); - - q_free(q); - }); - - CMC_CREATE_TEST(count, { - struct queue *q = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q); - - cmc_assert_equals(size_t, 0, q_count(q)); - - for (size_t i = 0; i < 100; i++) - cmc_assert(q_enqueue(q, i)); - - cmc_assert_equals(size_t, 100, q_count(q)); - - q_free(q); - }); - - CMC_CREATE_TEST(capacity, { - struct queue *q = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q); - - cmc_assert_equals(size_t, 100, q_capacity(q)); - - q_free(q); - }); - - CMC_CREATE_TEST(resize, { - struct queue *q = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q); - - for (size_t i = 0; i < 150; i++) - cmc_assert(q_enqueue(q, i)); - - cmc_assert_equals(size_t, 150, q_count(q)); - cmc_assert(q_resize(q, q_count(q))); - cmc_assert_equals(size_t, 150, q_capacity(q)); - - q_free(q); - }); - - CMC_CREATE_TEST(resize[item preservation], { - struct queue *q = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q); - - for (size_t i = 1; i <= 150; i++) - cmc_assert(q_enqueue(q, i)); - - cmc_assert(q_resize(q, q_count(q))); - - size_t sum = 0; - - for (size_t i = q->front, j = 0; j < q->count; i = (i + 1) % q->capacity, j++) - { - sum += q->buffer[i]; - } - - cmc_assert_equals(size_t, 11325, sum); - - q_free(q); - }); - - CMC_CREATE_TEST(copy_of, { - struct queue *q1 = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q1); - - for (size_t i = 1; i <= 150; i++) - cmc_assert(q_enqueue(q1, i)); - - struct queue *q2 = q_copy_of(q1); - - cmc_assert_not_equals(ptr, NULL, q2); - cmc_assert_equals(size_t, q_count(q1), q_count(q2)); - - for (size_t i1 = q1->front, i2 = q2->front, j = 0; j < q1->count; j++) - { - cmc_assert_equals(size_t, q1->buffer[i1], q2->buffer[i2]); - - i1 = (i1 + 1) % q1->capacity; - i2 = (i2 + 1) % q2->capacity; - } - - q_free(q1); - q_free(q2); - }); - - CMC_CREATE_TEST(equals, { - struct queue *q1 = q_new(100, q_fval); - struct queue *q2 = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q1); - cmc_assert_not_equals(ptr, NULL, q2); - - for (size_t i = 1; i <= 150; i++) - { - cmc_assert(q_enqueue(q1, i)); - cmc_assert(q_enqueue(q2, i)); - } - - cmc_assert(q_equals(q1, q2)); - - q_free(q1); - q_free(q2); - }); - - CMC_CREATE_TEST(equals[from copy], { - struct queue *q1 = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q1); - - for (size_t i = 1; i <= 150; i++) - { - cmc_assert(q_enqueue(q1, i)); - } - - struct queue *q2 = q_copy_of(q1); - - cmc_assert_not_equals(ptr, NULL, q2); - - cmc_assert(q_equals(q1, q2)); - - q_free(q1); - q_free(q2); - }); - - CMC_CREATE_TEST(equals[count = 0], { - struct queue *q1 = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q1); - - struct queue *q2 = q_copy_of(q1); - - cmc_assert_not_equals(ptr, NULL, q2); - - cmc_assert(q_equals(q1, q2)); - - q_free(q1); - q_free(q2); - }); - - CMC_CREATE_TEST(flag, { - struct queue *q = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q); - cmc_assert_equals(int32_t, CMC_FLAG_OK, q_flag(q)); - - // clear - q->flag = CMC_FLAG_ERROR; - q_clear(q); - cmc_assert_equals(int32_t, CMC_FLAG_OK, q_flag(q)); - - // customize - q->flag = CMC_FLAG_ERROR; - q_customize(q, NULL, NULL); - cmc_assert_equals(int32_t, CMC_FLAG_OK, q_flag(q)); - - // enqueue - q->flag = CMC_FLAG_ERROR; - q_enqueue(q, 10); - cmc_assert_equals(int32_t, CMC_FLAG_OK, q_flag(q)); - - // dequeue - q->flag = CMC_FLAG_ERROR; - q_dequeue(q); - cmc_assert_equals(int32_t, CMC_FLAG_OK, q_flag(q)); - - q_dequeue(q); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, q_flag(q)); - - // peek - q->flag = CMC_FLAG_ERROR; - q_peek(q); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, q_flag(q)); - - cmc_assert(q_enqueue(q, 10)); - q_peek(q); - cmc_assert_equals(int32_t, CMC_FLAG_OK, q_flag(q)); - - // contains - q->flag = CMC_FLAG_ERROR; - cmc_assert(q_contains(q, 10)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, q_flag(q)); - - // copy_of - q->flag = CMC_FLAG_OK; - struct queue *q2 = q_copy_of(q); - cmc_assert_equals(int32_t, CMC_FLAG_OK, q_flag(q)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, q_flag(q2)); - - // equals - q->flag = CMC_FLAG_OK; - q2->flag = CMC_FLAG_OK; - cmc_assert(q_equals(q, q2)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, q_flag(q)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, q_flag(q2)); - - q_free(q); - q_free(q2); - }); - - CMC_CREATE_TEST(callbacks, { - struct queue *q = q_new_custom(100, q_fval, NULL, callbacks); - - cmc_assert_not_equals(ptr, NULL, q); - - total_create = 0; - total_read = 0; - total_update = 0; - total_delete = 0; - total_resize = 0; - - cmc_assert(q_enqueue(q, 10)); - cmc_assert_equals(int32_t, 1, total_create); - - cmc_assert(q_dequeue(q)); - cmc_assert_equals(int32_t, 1, total_delete); - - cmc_assert(q_enqueue(q, 10)); - cmc_assert_equals(int32_t, 2, total_create); - - cmc_assert_equals(size_t, 10, q_peek(q)); - cmc_assert_equals(int32_t, 1, total_read); - - cmc_assert(q_contains(q, 10)); - cmc_assert_equals(int32_t, 2, total_read); - - cmc_assert(q_resize(q, 1000)); - cmc_assert_equals(int32_t, 1, total_resize); - - cmc_assert(q_resize(q, 100)); - cmc_assert_equals(int32_t, 2, total_resize); - - cmc_assert_equals(int32_t, 2, total_create); - cmc_assert_equals(int32_t, 2, total_read); - cmc_assert_equals(int32_t, 0, total_update); - cmc_assert_equals(int32_t, 1, total_delete); - cmc_assert_equals(int32_t, 2, total_resize); - - q_customize(q, NULL, NULL); - - cmc_assert_equals(ptr, NULL, q->callbacks); - - q_clear(q); - cmc_assert(q_enqueue(q, 10)); - cmc_assert(q_dequeue(q)); - cmc_assert(q_enqueue(q, 10)); - cmc_assert_equals(size_t, 10, q_peek(q)); - cmc_assert(q_contains(q, 10)); - cmc_assert(q_resize(q, 1000)); - cmc_assert(q_resize(q, 100)); - - cmc_assert_equals(int32_t, 2, total_create); - cmc_assert_equals(int32_t, 2, total_read); - cmc_assert_equals(int32_t, 0, total_update); - cmc_assert_equals(int32_t, 1, total_delete); - cmc_assert_equals(int32_t, 2, total_resize); - - cmc_assert_equals(ptr, NULL, q->callbacks); - - q_free(q); - - total_create = 0; - total_read = 0; - total_update = 0; - total_delete = 0; - total_resize = 0; - }); -}); - -CMC_CREATE_UNIT(CMCQueueIter, true, { - CMC_CREATE_TEST(PFX##_iter_start(), { - struct queue *q = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q); - - struct queue_iter it = q_iter_start(q); - - cmc_assert_equals(ptr, q, it.target); - cmc_assert_equals(size_t, q->front, it.cursor); - cmc_assert_equals(size_t, 0, it.index); - cmc_assert_equals(bool, true, it.start); - cmc_assert_equals(bool, true, it.end); - - cmc_assert(q_iter_at_start(&it)); - cmc_assert(q_iter_at_end(&it)); - - cmc_assert(q_enqueue(q, 1)); - cmc_assert(q_enqueue(q, 2)); - - it = q_iter_start(q); - - cmc_assert_equals(size_t, 0, it.index); - cmc_assert_equals(bool, false, it.end); - cmc_assert_equals(size_t, q->front, it.cursor); - - q_free(q); - }); - - CMC_CREATE_TEST(PFX##_iter_end(), { - struct queue *q = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q); - - struct queue_iter it = q_iter_end(q); - - cmc_assert_equals(ptr, q, it.target); - cmc_assert_equals(size_t, q->back, it.cursor); - cmc_assert_equals(size_t, 0, it.index); - cmc_assert_equals(bool, true, it.start); - cmc_assert_equals(bool, true, it.end); - - cmc_assert(q_iter_at_start(&it)); - cmc_assert(q_iter_at_end(&it)); - - cmc_assert(q_enqueue(q, 1)); - cmc_assert(q_enqueue(q, 2)); - cmc_assert(q_enqueue(q, 3)); - - it = q_iter_end(q); - - cmc_assert_equals(size_t, q->count - 1, it.index); - cmc_assert_equals(size_t, q->back - 1, it.cursor); - cmc_assert_equals(bool, false, it.start); - - q_free(q); - }); - - CMC_CREATE_TEST(PFX##_iter_at_start(), { - struct queue *q = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q); - - struct queue_iter it = q_iter_start(q); - - // Empty checks - cmc_assert(q_iter_at_start(&it)); - it = q_iter_end(q); - cmc_assert(q_iter_at_start(&it)); - - // Non-empty check - cmc_assert(q_enqueue(q, 1)); - it = q_iter_end(q); - cmc_assert(!q_iter_at_start(&it)); - it = q_iter_start(q); - cmc_assert(q_iter_at_start(&it)); - - q_free(q); - }); - - CMC_CREATE_TEST(PFX##_iter_at_end(), { - struct queue *q = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q); - - struct queue_iter it = q_iter_start(q); - - // Empty check - cmc_assert(q_iter_at_end(&it)); - it = q_iter_end(q); - cmc_assert(q_iter_at_end(&it)); - - // Non-empty check - cmc_assert(q_enqueue(q, 1)); - it = q_iter_end(q); - cmc_assert(q_iter_at_end(&it)); - it = q_iter_start(q); - cmc_assert(!q_iter_at_end(&it)); - - q_free(q); - }); - - CMC_CREATE_TEST(PFX##_iter_to_start(), { - struct queue *q = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q); - - struct queue_iter it = q_iter_start(q); - - cmc_assert(!q_iter_to_start(&it)); - - for (size_t i = 1; i <= 100; i++) - q_enqueue(q, i); - - cmc_assert_equals(size_t, 100, q->count); - - it = q_iter_end(q); - - cmc_assert(!q_iter_at_start(&it)); - cmc_assert(q_iter_at_end(&it)); - - cmc_assert_equals(size_t, 100, q_iter_value(&it)); - - cmc_assert(q_iter_to_start(&it)); - - cmc_assert(q_iter_at_start(&it)); - cmc_assert(!q_iter_at_end(&it)); - - cmc_assert_equals(size_t, 1, q_iter_value(&it)); - - q_free(q); - }); - - CMC_CREATE_TEST(PFX##_iter_to_end(), { - struct queue *q = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q); - - struct queue_iter it = q_iter_end(q); - - cmc_assert(!q_iter_to_end(&it)); - - for (size_t i = 1; i <= 100; i++) - q_enqueue(q, i); - - it = q_iter_start(q); - - cmc_assert(q_iter_at_start(&it)); - cmc_assert(!q_iter_at_end(&it)); - - cmc_assert_equals(size_t, 1, q_iter_value(&it)); - - cmc_assert(q_iter_to_end(&it)); - - cmc_assert(!q_iter_at_start(&it)); - cmc_assert(q_iter_at_end(&it)); - - cmc_assert_equals(size_t, 100, q_iter_value(&it)); - - q_free(q); - }); - - CMC_CREATE_TEST(PFX##_iter_next(), { - struct queue *q = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q); - - struct queue_iter it = q_iter_start(q); - - cmc_assert(!q_iter_next(&it)); - - for (size_t i = 1; i <= 1000; i++) - q_enqueue(q, i); - - size_t sum = 0; - for (it = q_iter_start(q); !q_iter_at_end(&it); q_iter_next(&it)) - { - sum += q_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - - q_iter_to_start(&it); - do - { - sum += q_iter_value(&it); - } while (q_iter_next(&it)); - - cmc_assert_equals(size_t, 500500, sum); - - q_free(q); - }); - - CMC_CREATE_TEST(PFX##_iter_prev(), { - struct queue *q = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q); - - struct queue_iter it = q_iter_end(q); - - cmc_assert(!q_iter_prev(&it)); - - for (size_t i = 1; i <= 1000; i++) - q_enqueue(q, i); - - size_t sum = 0; - for (it = q_iter_end(q); !q_iter_at_start(&it); q_iter_prev(&it)) - { - sum += q_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - - q_iter_to_end(&it); - do - { - sum += q_iter_value(&it); - } while (q_iter_prev(&it)); - - cmc_assert_equals(size_t, 500500, sum); - - q_free(q); - }); - - CMC_CREATE_TEST(PFX##_iter_advance(), { - struct queue *q = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q); - - struct queue_iter it = q_iter_start(q); - - cmc_assert(!q_iter_advance(&it, 1)); - - for (size_t i = 0; i <= 1000; i++) - q_enqueue(q, i); - - it = q_iter_start(q); - - cmc_assert(!q_iter_advance(&it, 0)); - cmc_assert(!q_iter_advance(&it, q->count)); - - size_t sum = 0; - for (it = q_iter_start(q);;) - { - sum += q_iter_value(&it); - - if (!q_iter_advance(&it, 2)) - break; - } - - cmc_assert_equals(size_t, 250500, sum); - - q_iter_to_start(&it); - cmc_assert(q_iter_advance(&it, q->count - 1)); - - q_free(q); - }); - - CMC_CREATE_TEST(PFX##_iter_rewind(), { - struct queue *q = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q); - - struct queue_iter it = q_iter_end(q); - - cmc_assert(!q_iter_rewind(&it, 1)); - - for (size_t i = 0; i <= 1000; i++) - q_enqueue(q, i); - - it = q_iter_end(q); - - cmc_assert(!q_iter_rewind(&it, 0)); - cmc_assert(!q_iter_rewind(&it, q->count)); - - size_t sum = 0; - for (it = q_iter_end(q);;) - { - sum += q_iter_value(&it); - - if (!q_iter_rewind(&it, 2)) - break; - } - - cmc_assert_equals(size_t, 250500, sum); - - q_iter_to_end(&it); - cmc_assert(q_iter_rewind(&it, q->count - 1)); - - q_free(q); - }); - - CMC_CREATE_TEST(PFX##_iter_go_to(), { - struct queue *q = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q); - - struct queue_iter it = q_iter_end(q); - cmc_assert(!q_iter_go_to(&it, 0)); - - it = q_iter_start(q); - cmc_assert(!q_iter_go_to(&it, 0)); - - for (size_t i = 0; i <= 1000; i++) - q_enqueue(q, i); - - it = q_iter_start(q); - - size_t sum = 0; - for (size_t i = 0; i < 1001; i++) - { - q_iter_go_to(&it, i); - - sum += q_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - for (size_t i = 1001; i > 0; i--) - { - cmc_assert(q_iter_go_to(&it, i - 1)); - - sum += q_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - for (size_t i = 0; i < 1001; i += 100) - { - cmc_assert(q_iter_go_to(&it, i)); - cmc_assert_equals(size_t, i, q_iter_index(&it)); - - sum += q_iter_value(&it); - } - - cmc_assert_equals(size_t, 5500, sum); - - q_free(q); - }); - - CMC_CREATE_TEST(PFX##_iter_value(), { - struct queue *q = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q); - - struct queue_iter it = q_iter_end(q); - - cmc_assert_equals(size_t, (size_t){ 0 }, q_iter_value(&it)); - - cmc_assert(q_enqueue(q, 10)); - - it = q_iter_start(q); - - cmc_assert_equals(size_t, 10, q_iter_value(&it)); - - q_free(q); - }); - - CMC_CREATE_TEST(PFX##_iter_rvalue(), { - struct queue *q = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q); - - struct queue_iter it = q_iter_end(q); - - cmc_assert_equals(ptr, NULL, q_iter_rvalue(&it)); - - cmc_assert(q_enqueue(q, 10)); - - it = q_iter_start(q); - - cmc_assert_not_equals(ptr, NULL, q_iter_rvalue(&it)); - cmc_assert_equals(size_t, 10, *q_iter_rvalue(&it)); - - q_free(q); - }); - - CMC_CREATE_TEST(PFX##_iter_index(), { - struct queue *q = q_new(100, q_fval); - - cmc_assert_not_equals(ptr, NULL, q); - - for (size_t i = 0; i <= 1000; i++) - q_enqueue(q, i); - - struct queue_iter it = q_iter_start(q); - - for (size_t i = 0; i < 1001; i++) - { - cmc_assert_equals(size_t, i, q_iter_index(&it)); - q_iter_next(&it); - } - - it = q_iter_end(q); - for (size_t i = 1001; i > 0; i--) - { - cmc_assert_equals(size_t, i - 1, q_iter_index(&it)); - q_iter_prev(&it); - } - - q_free(q); - }); -}); - -#ifdef CMC_TEST_MAIN -int main(void) -{ - int result = CMCQueue() + CMCQueueIter(); - - printf(" +---------------------------------------------------------------+"); - printf("\n"); - printf(" | CMCQueue Suit : %-48s |\n", result == 0 ? "PASSED" : "FAILED"); - printf(" +---------------------------------------------------------------+"); - printf("\n\n\n"); - - return result; -} -#endif - -#endif /* CMC_TESTS_UNT_CMC_QUEUE_H */ diff --git a/tests/unt/unt_cmc_sortedlist.h b/tests/unt/unt_cmc_sortedlist.h deleted file mode 100644 index 103e56b..0000000 --- a/tests/unt/unt_cmc_sortedlist.h +++ /dev/null @@ -1,714 +0,0 @@ -#ifndef CMC_TESTS_UNT_CMC_SORTEDLIST_H -#define CMC_TESTS_UNT_CMC_SORTEDLIST_H - -#include "utl.h" - -#include "tst_cmc_sortedlist.h" - -struct sortedlist_fval *sl_fval = &(struct sortedlist_fval){ - .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp -}; - -CMC_CREATE_UNIT(CMCSortedList, true, { - CMC_CREATE_TEST(new, { - struct sortedlist *sl = sl_new(1000000, sl_fval); - - cmc_assert_not_equals(ptr, NULL, sl); - cmc_assert_not_equals(ptr, NULL, sl->buffer); - cmc_assert_equals(size_t, 1000000, sl_capacity(sl)); - cmc_assert_equals(size_t, 0, sl_count(sl)); - cmc_assert_not_equals(ptr, NULL, sl->buffer); - - sl_free(sl); - }); - - CMC_CREATE_TEST(new[capacity = 0], { - struct sortedlist *sl = sl_new(0, sl_fval); - - cmc_assert_equals(ptr, NULL, sl); - }); - - CMC_CREATE_TEST(new[capacity = UINT64_MAX], { - struct sortedlist *sl = sl_new(UINT64_MAX, sl_fval); - - cmc_assert_equals(ptr, NULL, sl); - }); - - CMC_CREATE_TEST(clear[count capacity], { - struct sortedlist *sl = sl_new(100, sl_fval); - - cmc_assert_not_equals(ptr, NULL, sl); - - for (size_t i = 0; i < 50; i++) - cmc_assert(sl_insert(sl, i)); - - cmc_assert_equals(size_t, 50, sl_count(sl)); - - sl_clear(sl); - - cmc_assert_equals(size_t, 0, sl_count(sl)); - cmc_assert_equals(size_t, 100, sl_capacity(sl)); - - sl_free(sl); - }); - - CMC_CREATE_TEST(buffer_growth[capacity = 1], { - struct sortedlist *sl = sl_new(1, sl_fval); - - cmc_assert_not_equals(ptr, NULL, sl); - - for (size_t i = 0; i < 50; i++) - cmc_assert(sl_insert(sl, i)); - - sl_sort(sl); - - cmc_assert_equals(size_t, 50, sl_count(sl)); - cmc_assert_array_sorted_any(size_t, sl->buffer, cmc_size_cmp, 0, sl->count - 1); - - sl_free(sl); - }); - - CMC_CREATE_TEST(insert, { - struct sortedlist *sl = sl_new(100, sl_fval); - - cmc_assert_not_equals(ptr, NULL, sl); - - cmc_assert(sl_insert(sl, 1)); - - sl_free(sl); - }); - - CMC_CREATE_TEST(remove, { - struct sortedlist *sl = sl_new(100, sl_fval); - - cmc_assert_not_equals(ptr, NULL, sl); - - cmc_assert(sl_insert(sl, 32)); - - cmc_assert(sl_remove(sl, 0)); - - sl_free(sl); - }); - - CMC_CREATE_TEST(remove[count = 0], { - struct sortedlist *sl = sl_new(100, sl_fval); - - cmc_assert_not_equals(ptr, NULL, sl); - - cmc_assert(!sl_remove(sl, 0)); - - sl_free(sl); - }); - - CMC_CREATE_TEST(remove[out of range], { - struct sortedlist *sl = sl_new(100, sl_fval); - - cmc_assert_not_equals(ptr, NULL, sl); - - cmc_assert(sl_insert(sl, 32)); - - cmc_assert(!sl_remove(sl, 2)); - - sl_free(sl); - }); - - CMC_CREATE_TEST(index_of, { - struct sortedlist *sl = sl_new(1, sl_fval); - - cmc_assert_not_equals(ptr, NULL, sl); - - for (size_t i = 0; i < 20; i++) - cmc_assert(sl_insert(sl, i % 10)); - - /* 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9 */ - cmc_assert_equals(size_t, 4, sl_index_of(sl, 2, true)); - cmc_assert_equals(size_t, 5, sl_index_of(sl, 2, false)); - - cmc_assert_equals(size_t, 0, sl_index_of(sl, 0, true)); - cmc_assert_equals(size_t, 1, sl_index_of(sl, 0, false)); - - cmc_assert(sl_remove(sl, 0)); - - cmc_assert_equals(size_t, 0, sl_index_of(sl, 0, true)); - cmc_assert_equals(size_t, 0, sl_index_of(sl, 0, false)); - - cmc_assert(sl_remove(sl, 0)); - - cmc_assert_equals(size_t, sl_count(sl), sl_index_of(sl, 0, true)); - cmc_assert_equals(size_t, sl_count(sl), sl_index_of(sl, 0, false)); - - sl_free(sl); - }); - - CMC_CREATE_TEST(flags, { - struct sortedlist *sl = sl_new(100, sl_fval); - - cmc_assert_not_equals(ptr, NULL, sl); - cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl)); - - // clear - sl->flag = CMC_FLAG_ERROR; - sl_clear(sl); - cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl)); - - // customize - sl->flag = CMC_FLAG_ERROR; - sl_customize(sl, NULL, NULL); - cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl)); - - // insert - sl->flag = CMC_FLAG_ERROR; - cmc_assert(sl_insert(sl, 10)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl)); - - // remove - cmc_assert(!sl_remove(sl, 2)); - cmc_assert_equals(int32_t, CMC_FLAG_RANGE, sl_flag(sl)); - - cmc_assert(sl_remove(sl, 0)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl)); - - cmc_assert(!sl_remove(sl, 0)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, sl_flag(sl)); - - // max min - sl->flag = CMC_FLAG_ERROR; - cmc_assert_equals(size_t, (size_t){ 0 }, sl_max(sl)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, sl_flag(sl)); - sl->flag = CMC_FLAG_ERROR; - cmc_assert_equals(size_t, (size_t){ 0 }, sl_min(sl)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, sl_flag(sl)); - - cmc_assert(sl_insert(sl, 1)); - sl->flag = CMC_FLAG_ERROR; - cmc_assert_equals(size_t, 1, sl_max(sl)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl)); - sl->flag = CMC_FLAG_ERROR; - cmc_assert_equals(size_t, 1, sl_min(sl)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl)); - - // get - sl->flag = CMC_FLAG_ERROR; - sl_get(sl, 1); - cmc_assert_equals(int32_t, CMC_FLAG_RANGE, sl_flag(sl)); - - sl_get(sl, 0); - cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl)); - - cmc_assert(sl_remove(sl, 0)); - sl_get(sl, 0); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, sl_flag(sl)); - - // index_of - cmc_assert(sl_insert(sl, 1)); - sl_index_of(sl, 1, false); - cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl)); - - // contains - cmc_assert(sl_contains(sl, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl)); - - // sort - sl->flag = CMC_FLAG_ERROR; - sl_sort(sl); - cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl)); - - // copy_of - sl->flag = CMC_FLAG_ERROR; - struct sortedlist *sl2 = sl_copy_of(sl); - cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl2)); - - // equals - sl->flag = CMC_FLAG_ERROR; - sl2->flag = CMC_FLAG_ERROR; - cmc_assert(sl_equals(sl, sl2)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl2)); - - sl_free(sl); - sl_free(sl2); - }); - - CMC_CREATE_TEST(callbacks, { - struct sortedlist *sl = sl_new_custom(100, sl_fval, NULL, callbacks); - - cmc_assert_not_equals(ptr, NULL, sl); - - total_create = 0; - total_read = 0; - total_update = 0; - total_delete = 0; - total_resize = 0; - - cmc_assert(sl_insert(sl, 10)); - cmc_assert_equals(int32_t, 1, total_create); - - cmc_assert(sl_remove(sl, 0)); - cmc_assert_equals(int32_t, 1, total_delete); - - cmc_assert(sl_insert(sl, 1)); - cmc_assert(sl_insert(sl, 0)); - cmc_assert_equals(int32_t, 3, total_create); - - cmc_assert_equals(size_t, 1, sl_max(sl)); - cmc_assert_equals(int32_t, 1, total_read); - - cmc_assert_equals(size_t, 0, sl_min(sl)); - cmc_assert_equals(int32_t, 2, total_read); - - cmc_assert_equals(size_t, 0, sl_get(sl, 0)); - cmc_assert_equals(int32_t, 3, total_read); - - cmc_assert_equals(size_t, 0, sl_index_of(sl, 0, true)); - cmc_assert_equals(int32_t, 4, total_read); - - cmc_assert(sl_contains(sl, 1)); - cmc_assert_equals(int32_t, 5, total_read); - - cmc_assert(sl_resize(sl, 1000)); - cmc_assert_equals(int32_t, 1, total_resize); - - cmc_assert(sl_resize(sl, 50)); - cmc_assert_equals(int32_t, 2, total_resize); - - cmc_assert_equals(int32_t, 3, total_create); - cmc_assert_equals(int32_t, 5, total_read); - cmc_assert_equals(int32_t, 0, total_update); - cmc_assert_equals(int32_t, 1, total_delete); - cmc_assert_equals(int32_t, 2, total_resize); - - sl_customize(sl, NULL, NULL); - - sl_clear(sl); - cmc_assert(sl_insert(sl, 10)); - cmc_assert(sl_remove(sl, 0)); - cmc_assert(sl_insert(sl, 1)); - cmc_assert(sl_insert(sl, 0)); - cmc_assert_equals(size_t, 1, sl_max(sl)); - cmc_assert_equals(size_t, 0, sl_min(sl)); - cmc_assert_equals(size_t, 0, sl_get(sl, 0)); - cmc_assert_equals(size_t, 0, sl_index_of(sl, 0, true)); - cmc_assert(sl_contains(sl, 1)); - - cmc_assert_equals(int32_t, 3, total_create); - cmc_assert_equals(int32_t, 5, total_read); - cmc_assert_equals(int32_t, 0, total_update); - cmc_assert_equals(int32_t, 1, total_delete); - cmc_assert_equals(int32_t, 2, total_resize); - - cmc_assert_equals(ptr, NULL, sl->callbacks); - - sl_free(sl); - - total_create = 0; - total_read = 0; - total_update = 0; - total_delete = 0; - total_resize = 0; - }); -}); - -CMC_CREATE_UNIT(CMCSortedListIter, true, { - CMC_CREATE_TEST(PFX##_iter_start(), { - struct sortedlist *sl = sl_new(100, sl_fval); - - cmc_assert_not_equals(ptr, NULL, sl); - - struct sortedlist_iter it = sl_iter_start(sl); - - cmc_assert_equals(ptr, sl, it.target); - cmc_assert_equals(size_t, 0, it.cursor); - cmc_assert_equals(bool, true, it.start); - cmc_assert_equals(bool, true, it.end); - - cmc_assert(sl_iter_at_start(&it)); - cmc_assert(sl_iter_at_end(&it)); - - cmc_assert(sl_insert(sl, 1)); - cmc_assert(sl_insert(sl, 2)); - - it = sl_iter_start(sl); - - cmc_assert_equals(size_t, 0, it.cursor); - cmc_assert_equals(bool, false, it.end); - - sl_free(sl); - }); - - CMC_CREATE_TEST(PFX##_iter_end(), { - struct sortedlist *sl = sl_new(100, sl_fval); - - cmc_assert_not_equals(ptr, NULL, sl); - - struct sortedlist_iter it = sl_iter_end(sl); - - cmc_assert_equals(ptr, sl, it.target); - cmc_assert_equals(size_t, 0, it.cursor); - cmc_assert_equals(bool, true, it.start); - cmc_assert_equals(bool, true, it.end); - - cmc_assert(sl_iter_at_start(&it)); - cmc_assert(sl_iter_at_end(&it)); - - cmc_assert(sl_insert(sl, 1)); - cmc_assert(sl_insert(sl, 2)); - cmc_assert(sl_insert(sl, 3)); - - it = sl_iter_end(sl); - - cmc_assert_equals(size_t, sl->count - 1, it.cursor); - cmc_assert_equals(bool, false, it.start); - - sl_free(sl); - }); - - CMC_CREATE_TEST(PFX##_iter_at_start(), { - struct sortedlist *sl = sl_new(100, sl_fval); - - cmc_assert_not_equals(ptr, NULL, sl); - - struct sortedlist_iter it = sl_iter_start(sl); - - // Empty checks - cmc_assert(sl_iter_at_start(&it)); - it = sl_iter_end(sl); - cmc_assert(sl_iter_at_start(&it)); - - // Non-empty checks - cmc_assert(sl_insert(sl, 1)); - it = sl_iter_end(sl); - cmc_assert(!sl_iter_at_start(&it)); - it = sl_iter_start(sl); - cmc_assert(sl_iter_at_start(&it)); - - sl_free(sl); - }); - - CMC_CREATE_TEST(PFX##_iter_at_end(), { - struct sortedlist *sl = sl_new(100, sl_fval); - - cmc_assert_not_equals(ptr, NULL, sl); - - struct sortedlist_iter it = sl_iter_start(sl); - - // Empty check - cmc_assert(sl_iter_at_end(&it)); - it = sl_iter_end(sl); - cmc_assert(sl_iter_at_end(&it)); - - // Non-empty checks - cmc_assert(sl_insert(sl, 1)); - it = sl_iter_end(sl); - cmc_assert(sl_iter_at_end(&it)); - it = sl_iter_start(sl); - cmc_assert(!sl_iter_at_end(&it)); - - sl_free(sl); - }); - - CMC_CREATE_TEST(PFX##_iter_to_start(), { - struct sortedlist *sl = sl_new(100, sl_fval); - - cmc_assert_not_equals(ptr, NULL, sl); - - struct sortedlist_iter it = sl_iter_start(sl); - - cmc_assert(!sl_iter_to_start(&it)); - - for (size_t i = 1; i <= 100; i++) - sl_insert(sl, i); - - cmc_assert_equals(size_t, 100, sl->count); - - it = sl_iter_end(sl); - - cmc_assert(!sl_iter_at_start(&it)); - cmc_assert(sl_iter_at_end(&it)); - - cmc_assert_equals(size_t, 100, sl_iter_value(&it)); - - cmc_assert(sl_iter_to_start(&it)); - - cmc_assert(sl_iter_at_start(&it)); - cmc_assert(!sl_iter_at_end(&it)); - - cmc_assert_equals(size_t, 1, sl_iter_value(&it)); - - sl_free(sl); - }); - - CMC_CREATE_TEST(PFX##_iter_to_end(), { - struct sortedlist *sl = sl_new(100, sl_fval); - - cmc_assert_not_equals(ptr, NULL, sl); - - struct sortedlist_iter it = sl_iter_end(sl); - - cmc_assert(!sl_iter_to_end(&it)); - - for (size_t i = 1; i <= 100; i++) - sl_insert(sl, i); - - it = sl_iter_start(sl); - - cmc_assert(sl_iter_at_start(&it)); - cmc_assert(!sl_iter_at_end(&it)); - - cmc_assert_equals(size_t, 1, sl_iter_value(&it)); - - cmc_assert(sl_iter_to_end(&it)); - - cmc_assert(!sl_iter_at_start(&it)); - cmc_assert(sl_iter_at_end(&it)); - - cmc_assert_equals(size_t, 100, sl_iter_value(&it)); - - sl_free(sl); - }); - - CMC_CREATE_TEST(PFX##_iter_next(), { - struct sortedlist *sl = sl_new(100, sl_fval); - - cmc_assert_not_equals(ptr, NULL, sl); - - struct sortedlist_iter it = sl_iter_start(sl); - - cmc_assert(!sl_iter_next(&it)); - - for (size_t i = 1; i <= 1000; i++) - sl_insert(sl, i); - - size_t sum = 0; - for (it = sl_iter_start(sl); !sl_iter_at_end(&it); sl_iter_next(&it)) - { - sum += sl_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - - sl_iter_to_start(&it); - do - { - sum += sl_iter_value(&it); - } while (sl_iter_next(&it)); - - cmc_assert_equals(size_t, 500500, sum); - - sl_free(sl); - }); - - CMC_CREATE_TEST(PFX##_iter_prev(), { - struct sortedlist *sl = sl_new(100, sl_fval); - - cmc_assert_not_equals(ptr, NULL, sl); - - struct sortedlist_iter it = sl_iter_end(sl); - - cmc_assert(!sl_iter_prev(&it)); - - for (size_t i = 1; i <= 1000; i++) - sl_insert(sl, i); - - size_t sum = 0; - for (it = sl_iter_end(sl); !sl_iter_at_start(&it); sl_iter_prev(&it)) - { - sum += sl_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - - sl_iter_to_end(&it); - do - { - sum += sl_iter_value(&it); - } while (sl_iter_prev(&it)); - - cmc_assert_equals(size_t, 500500, sum); - - sl_free(sl); - }); - - CMC_CREATE_TEST(PFX##_iter_advance(), { - struct sortedlist *sl = sl_new(100, sl_fval); - - cmc_assert_not_equals(ptr, NULL, sl); - - struct sortedlist_iter it = sl_iter_start(sl); - - cmc_assert(!sl_iter_advance(&it, 1)); - - for (size_t i = 0; i <= 1000; i++) - sl_insert(sl, i); - - it = sl_iter_start(sl); - - cmc_assert(!sl_iter_advance(&it, 0)); - cmc_assert(!sl_iter_advance(&it, sl->count)); - - size_t sum = 0; - for (it = sl_iter_start(sl);;) - { - sum += sl_iter_value(&it); - - if (!sl_iter_advance(&it, 2)) - break; - } - - cmc_assert_equals(size_t, 250500, sum); - - sl_iter_to_start(&it); - cmc_assert(sl_iter_advance(&it, sl->count - 1)); - - sl_free(sl); - }); - - CMC_CREATE_TEST(PFX##_iter_rewind(), { - struct sortedlist *sl = sl_new(100, sl_fval); - - cmc_assert_not_equals(ptr, NULL, sl); - - struct sortedlist_iter it = sl_iter_end(sl); - - cmc_assert(!sl_iter_rewind(&it, 1)); - - for (size_t i = 0; i <= 1000; i++) - sl_insert(sl, i); - - it = sl_iter_end(sl); - - cmc_assert(!sl_iter_rewind(&it, 0)); - cmc_assert(!sl_iter_rewind(&it, sl->count)); - - size_t sum = 0; - for (it = sl_iter_end(sl);;) - { - sum += sl_iter_value(&it); - - if (!sl_iter_rewind(&it, 2)) - break; - } - - cmc_assert_equals(size_t, 250500, sum); - - sl_iter_to_end(&it); - cmc_assert(sl_iter_rewind(&it, sl->count - 1)); - - sl_free(sl); - }); - - CMC_CREATE_TEST(PFX##_iter_go_to(), { - struct sortedlist *sl = sl_new(100, sl_fval); - - cmc_assert_not_equals(ptr, NULL, sl); - - struct sortedlist_iter it = sl_iter_end(sl); - cmc_assert(!sl_iter_go_to(&it, 0)); - - it = sl_iter_start(sl); - cmc_assert(!sl_iter_go_to(&it, 0)); - - for (size_t i = 0; i <= 1000; i++) - sl_insert(sl, i); - - it = sl_iter_start(sl); - - size_t sum = 0; - for (size_t i = 0; i < 1001; i++) - { - sl_iter_go_to(&it, i); - - sum += sl_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - for (size_t i = 1001; i > 0; i--) - { - cmc_assert(sl_iter_go_to(&it, i - 1)); - - sum += sl_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - for (size_t i = 0; i < 1001; i += 100) - { - cmc_assert(sl_iter_go_to(&it, i)); - cmc_assert_equals(size_t, i, sl_iter_index(&it)); - - sum += sl_iter_value(&it); - } - - cmc_assert_equals(size_t, 5500, sum); - - sl_free(sl); - }); - - CMC_CREATE_TEST(PFX##_iter_value(), { - struct sortedlist *sl = sl_new(100, sl_fval); - - cmc_assert_not_equals(ptr, NULL, sl); - - struct sortedlist_iter it = sl_iter_end(sl); - - cmc_assert_equals(size_t, (size_t){ 0 }, sl_iter_value(&it)); - - cmc_assert(sl_insert(sl, 10)); - - it = sl_iter_start(sl); - - cmc_assert_equals(size_t, 10, sl_iter_value(&it)); - - sl_free(sl); - }); - - CMC_CREATE_TEST(PFX##_iter_index(), { - struct sortedlist *sl = sl_new(100, sl_fval); - - cmc_assert_not_equals(ptr, NULL, sl); - - for (size_t i = 0; i <= 1000; i++) - sl_insert(sl, i); - - struct sortedlist_iter it = sl_iter_start(sl); - - for (size_t i = 0; i < 1001; i++) - { - cmc_assert_equals(size_t, i, sl_iter_index(&it)); - sl_iter_next(&it); - } - - it = sl_iter_end(sl); - for (size_t i = 1001; i > 0; i--) - { - cmc_assert_equals(size_t, i - 1, sl_iter_index(&it)); - sl_iter_prev(&it); - } - - sl_free(sl); - }); -}); - -#ifdef CMC_TEST_MAIN -int main(void) -{ - int result = CMCSortedList() + CMCSortedListIter(); - - printf(" +---------------------------------------------------------------+"); - printf("\n"); - printf(" | CMCSortedList Suit : %-43s |\n", result == 0 ? "PASSED" : "FAILED"); - printf(" +---------------------------------------------------------------+"); - printf("\n\n\n"); - - return result; -} -#endif - -#endif /* CMC_TESTS_UNT_CMC_SORTEDLIST_H */ diff --git a/tests/unt/unt_cmc_stack.h b/tests/unt/unt_cmc_stack.h deleted file mode 100644 index 6cabe92..0000000 --- a/tests/unt/unt_cmc_stack.h +++ /dev/null @@ -1,849 +0,0 @@ -#ifndef CMC_TESTS_UNT_CMC_STACK_H -#define CMC_TESTS_UNT_CMC_STACK_H - -#include "utl.h" - -#include "tst_cmc_stack.h" - -struct stack_fval *s_fval = &(struct stack_fval){ - .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp -}; - -CMC_CREATE_UNIT(CMCStack, true, { - CMC_CREATE_TEST(new, { - struct stack *s = s_new(1000000, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - 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); - - s_free(s); - }); - - CMC_CREATE_TEST(new[capacity = 0], { - struct stack *s = s_new(0, s_fval); - - cmc_assert_equals(ptr, NULL, s); - }); - - CMC_CREATE_TEST(new[capacity = UINT64_MAX], { - struct stack *s = s_new(UINT64_MAX, s_fval); - - cmc_assert_equals(ptr, NULL, s); - }); - - CMC_CREATE_TEST(clear[count capacity], { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - for (size_t i = 0; i < 50; i++) - cmc_assert(s_push(s, i)); - - cmc_assert_equals(size_t, 50, s_count(s)); - - s_clear(s); - - cmc_assert_equals(size_t, 0, s_count(s)); - cmc_assert_equals(size_t, 100, s_capacity(s)); - - s_free(s); - }); - - CMC_CREATE_TEST(buffer_growth[capacity = 1], { - struct stack *s = s_new(1, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - for (size_t i = 0; i < 50; i++) - cmc_assert(s_push(s, i)); - - cmc_assert_equals(size_t, 50, s_count(s)); - cmc_assert_lesser_equals(size_t, s_capacity(s), s_count(s)); - - s_free(s); - }); - - CMC_CREATE_TEST(push[count], { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - for (size_t i = 0; i < 250; i++) - cmc_assert(s_push(s, i)); - - cmc_assert_equals(size_t, 250, s_count(s)); - - s_free(s); - }); - - CMC_CREATE_TEST(push[capacity], { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - for (size_t i = 0; i < 250; i++) - cmc_assert(s_push(s, i)); - - cmc_assert_lesser_equals(size_t, s_capacity(s), s_count(s)); - - s_free(s); - }); - - CMC_CREATE_TEST(push[item preservation], { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - for (size_t i = 0; i < 250; i++) - cmc_assert(s_push(s, i)); - - for (size_t i = 0; i < s_count(s); i++) - cmc_assert_equals(size_t, i, s->buffer[i]); - - s_free(s); - }); - - CMC_CREATE_TEST(pop[count], { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - for (size_t i = 0; i < 250; i++) - cmc_assert(s_push(s, i)); - - cmc_assert(s_pop(s)); - - cmc_assert_equals(size_t, 249, s_count(s)); - - s_free(s); - }); - - CMC_CREATE_TEST(pop[capacity], { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - for (size_t i = 0; i < 250; i++) - cmc_assert(s_push(s, i)); - - cmc_assert(s_pop(s)); - - cmc_assert_lesser_equals(size_t, s_capacity(s), s_count(s)); - - s_free(s); - }); - - CMC_CREATE_TEST(pop[item preservation], { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - for (size_t i = 0; i < 250; i++) - cmc_assert(s_push(s, i)); - - cmc_assert(s_pop(s)); - cmc_assert(s_pop(s)); - - for (size_t i = 0; i < s_count(s); i++) - cmc_assert_equals(size_t, i, s->buffer[i]); - - s_free(s); - }); - - CMC_CREATE_TEST(pop[count = 0], { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - cmc_assert_equals(bool, false, s_pop(s)); - - s_free(s); - }); - - CMC_CREATE_TEST(top, { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - for (size_t i = 0; i < 250; i++) - cmc_assert(s_push(s, i)); - - cmc_assert(s_pop(s)); - cmc_assert(s_pop(s)); - - cmc_assert_equals(size_t, 247, s_top(s)); - - s_free(s); - }); - - CMC_CREATE_TEST(top[count = 0], { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - cmc_assert(s_push(s, 1)); - - cmc_assert(s_pop(s)); - - cmc_assert_equals(size_t, (size_t){ 0 }, s_top(s)); - - s_free(s); - }); - - CMC_CREATE_TEST(top[count = 1], { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - cmc_assert(s_push(s, 10)); - cmc_assert_equals(size_t, 1, s_count(s)); - cmc_assert_equals(size_t, 10, s_top(s)); - - s_free(s); - }); - - CMC_CREATE_TEST(contains, { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - for (size_t i = 0; i < 150; i++) - cmc_assert(s_push(s, i)); - - for (size_t i = 0; i < 150; i++) - cmc_assert(s_contains(s, i)); - - s_free(s); - }); - - CMC_CREATE_TEST(contains[count = 0], { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - cmc_assert_equals(bool, false, s_contains(s, 10)); - - s_free(s); - }); - - CMC_CREATE_TEST(empty, { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - cmc_assert(s_empty(s)); - - s_free(s); - }); - - CMC_CREATE_TEST(empty[after_io], { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - cmc_assert(s_push(s, 10)); - cmc_assert(s_pop(s)); - cmc_assert(s_empty(s)); - - s_free(s); - }); - - CMC_CREATE_TEST(full, { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - for (size_t i = 0; i < s_capacity(s); i++) - cmc_assert(s_push(s, i)); - - cmc_assert(s_full(s)); - - s_free(s); - }); - - CMC_CREATE_TEST(full[capacity = 1], { - struct stack *s = s_new(1, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - cmc_assert(s_push(s, 10)); - - cmc_assert(s_full(s)); - - s_free(s); - }); - - CMC_CREATE_TEST(flags, { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s)); - - // clear - s->flag = CMC_FLAG_ERROR; - s_clear(s); - cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s)); - - // customize - s->flag = CMC_FLAG_ERROR; - s_customize(s, NULL, NULL); - cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s)); - - // push - s->flag = CMC_FLAG_ERROR; - cmc_assert(s_push(s, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s)); - - // pop - s->flag = CMC_FLAG_ERROR; - cmc_assert(s_pop(s)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s)); - - cmc_assert(!s_pop(s)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, s_flag(s)); - - // top - s->flag = CMC_FLAG_ERROR; - s_top(s); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, s_flag(s)); - - cmc_assert(s_push(s, 1)); - s_top(s); - cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s)); - - // contains - s->flag = CMC_FLAG_ERROR; - cmc_assert(s_contains(s, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s)); - - // copy_of - s->flag = CMC_FLAG_ERROR; - struct stack *s2 = s_copy_of(s); - cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s2)); - - // equals - s->flag = CMC_FLAG_ERROR; - s2->flag = CMC_FLAG_ERROR; - cmc_assert(s_equals(s, s2)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s2)); - - s_free(s); - s_free(s2); - }); - - CMC_CREATE_TEST(callbacks, { - struct stack *s = s_new_custom(100, s_fval, NULL, callbacks); - - cmc_assert_not_equals(ptr, NULL, s); - - total_create = 0; - total_read = 0; - total_update = 0; - total_delete = 0; - total_resize = 0; - - cmc_assert(s_push(s, 10)); - cmc_assert_equals(int32_t, 1, total_create); - - cmc_assert(s_pop(s)); - cmc_assert_equals(int32_t, 1, total_delete); - - cmc_assert(s_push(s, 1)); - cmc_assert_equals(int32_t, 2, total_create); - - cmc_assert_equals(size_t, 1, s_top(s)); - cmc_assert_equals(int32_t, 1, total_read); - - cmc_assert(s_contains(s, 1)); - cmc_assert_equals(int32_t, 2, total_read); - - cmc_assert(s_resize(s, 1000)); - cmc_assert_equals(int32_t, 1, total_resize); - - cmc_assert(s_resize(s, 10)); - cmc_assert_equals(int32_t, 2, total_resize); - - cmc_assert_equals(int32_t, 2, total_create); - cmc_assert_equals(int32_t, 2, total_read); - cmc_assert_equals(int32_t, 0, total_update); - cmc_assert_equals(int32_t, 1, total_delete); - cmc_assert_equals(int32_t, 2, total_resize); - - s_customize(s, NULL, NULL); - - s_clear(s); - cmc_assert(s_push(s, 10)); - cmc_assert(s_pop(s)); - cmc_assert(s_push(s, 1)); - cmc_assert_equals(size_t, 1, s_top(s)); - cmc_assert(s_contains(s, 1)); - cmc_assert(s_resize(s, 1000)); - cmc_assert(s_resize(s, 10)); - - cmc_assert_equals(int32_t, 2, total_create); - cmc_assert_equals(int32_t, 2, total_read); - cmc_assert_equals(int32_t, 0, total_update); - cmc_assert_equals(int32_t, 1, total_delete); - cmc_assert_equals(int32_t, 2, total_resize); - - cmc_assert_equals(ptr, NULL, s->callbacks); - - s_free(s); - - total_create = 0; - total_read = 0; - total_update = 0; - total_delete = 0; - total_resize = 0; - }); -}); - -CMC_CREATE_UNIT(CMCStackIter, true, { - CMC_CREATE_TEST(PFX##_iter_start(), { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - struct stack_iter it = s_iter_start(s); - - cmc_assert_equals(ptr, s, it.target); - cmc_assert_equals(size_t, 0, it.cursor); - cmc_assert_equals(bool, true, it.start); - cmc_assert_equals(bool, true, it.end); - - cmc_assert(s_iter_at_start(&it)); - cmc_assert(s_iter_at_end(&it)); - - cmc_assert(s_push(s, 1)); - cmc_assert(s_push(s, 2)); - - it = s_iter_start(s); - - cmc_assert_equals(size_t, s->count - 1, it.cursor); - cmc_assert_equals(bool, false, it.end); - - s_free(s); - }); - - CMC_CREATE_TEST(PFX##_iter_end(), { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - struct stack_iter it = s_iter_end(s); - - cmc_assert_equals(ptr, s, it.target); - cmc_assert_equals(size_t, 0, it.cursor); - cmc_assert_equals(bool, true, it.start); - cmc_assert_equals(bool, true, it.end); - - cmc_assert(s_iter_at_start(&it)); - cmc_assert(s_iter_at_end(&it)); - - cmc_assert(s_push(s, 1)); - cmc_assert(s_push(s, 2)); - cmc_assert(s_push(s, 3)); - - it = s_iter_end(s); - - cmc_assert_equals(size_t, 0, it.cursor); - cmc_assert_equals(bool, false, it.start); - - s_free(s); - }); - - CMC_CREATE_TEST(PFX##_iter_at_start(), { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - struct stack_iter it = s_iter_start(s); - - // Empty checks - cmc_assert(s_iter_at_start(&it)); - it = s_iter_end(s); - cmc_assert(s_iter_at_start(&it)); - - // Non-empty checks - cmc_assert(s_push(s, 1)); - it = s_iter_end(s); - cmc_assert(!s_iter_at_start(&it)); - it = s_iter_start(s); - cmc_assert(s_iter_at_start(&it)); - - s_free(s); - }); - - CMC_CREATE_TEST(PFX##_iter_at_end(), { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - struct stack_iter it = s_iter_start(s); - - // Empty check - cmc_assert(s_iter_at_end(&it)); - it = s_iter_end(s); - cmc_assert(s_iter_at_end(&it)); - - // Non-empty checks - cmc_assert(s_push(s, 1)); - it = s_iter_end(s); - cmc_assert(s_iter_at_end(&it)); - it = s_iter_start(s); - cmc_assert(!s_iter_at_end(&it)); - - s_free(s); - }); - - CMC_CREATE_TEST(PFX##_iter_to_start(), { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - struct stack_iter it = s_iter_start(s); - - cmc_assert(!s_iter_to_start(&it)); - - for (size_t i = 1; i <= 100; i++) - s_push(s, i); - - cmc_assert_equals(size_t, 100, s->count); - - it = s_iter_end(s); - - cmc_assert(!s_iter_at_start(&it)); - cmc_assert(s_iter_at_end(&it)); - - cmc_assert_equals(size_t, 1, s_iter_value(&it)); - - cmc_assert(s_iter_to_start(&it)); - - cmc_assert(s_iter_at_start(&it)); - cmc_assert(!s_iter_at_end(&it)); - - cmc_assert_equals(size_t, 100, s_iter_value(&it)); - - s_free(s); - }); - - CMC_CREATE_TEST(PFX##_iter_to_end(), { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - struct stack_iter it = s_iter_end(s); - - cmc_assert(!s_iter_to_end(&it)); - - for (size_t i = 1; i <= 100; i++) - s_push(s, i); - - it = s_iter_start(s); - - cmc_assert(s_iter_at_start(&it)); - cmc_assert(!s_iter_at_end(&it)); - - cmc_assert_equals(size_t, 100, s_iter_value(&it)); - - cmc_assert(s_iter_to_end(&it)); - - cmc_assert(!s_iter_at_start(&it)); - cmc_assert(s_iter_at_end(&it)); - - cmc_assert_equals(size_t, 1, s_iter_value(&it)); - - s_free(s); - }); - - CMC_CREATE_TEST(PFX##_iter_next(), { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - struct stack_iter it = s_iter_start(s); - - cmc_assert(!s_iter_next(&it)); - - for (size_t i = 1; i <= 1000; i++) - s_push(s, i); - - size_t sum = 0; - for (it = s_iter_start(s); !s_iter_at_end(&it); s_iter_next(&it)) - { - sum += s_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - - s_iter_to_start(&it); - do - { - sum += s_iter_value(&it); - } while (s_iter_next(&it)); - - cmc_assert_equals(size_t, 500500, sum); - - s_free(s); - }); - - CMC_CREATE_TEST(PFX##_iter_prev(), { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - struct stack_iter it = s_iter_end(s); - - cmc_assert(!s_iter_prev(&it)); - - for (size_t i = 1; i <= 1000; i++) - s_push(s, i); - - size_t sum = 0; - for (it = s_iter_end(s); !s_iter_at_start(&it); s_iter_prev(&it)) - { - sum += s_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - - s_iter_to_end(&it); - do - { - sum += s_iter_value(&it); - } while (s_iter_prev(&it)); - - cmc_assert_equals(size_t, 500500, sum); - - s_free(s); - }); - - CMC_CREATE_TEST(PFX##_iter_advance(), { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - struct stack_iter it = s_iter_start(s); - - cmc_assert(!s_iter_advance(&it, 1)); - - for (size_t i = 0; i <= 1000; i++) - s_push(s, i); - - it = s_iter_start(s); - - cmc_assert(!s_iter_advance(&it, 0)); - cmc_assert(!s_iter_advance(&it, s->count)); - - size_t sum = 0; - for (it = s_iter_start(s);;) - { - sum += s_iter_value(&it); - - if (!s_iter_advance(&it, 2)) - break; - } - - cmc_assert_equals(size_t, 250500, sum); - - s_iter_to_start(&it); - cmc_assert(s_iter_advance(&it, s->count - 1)); - - // sum (1000, 990, 980, 970, ..., 910, 900) - sum = 0; - it = s_iter_start(s); - for (size_t val = s_iter_value(&it); val > 900; s_iter_advance(&it, 10)) - { - val = s_iter_value(&it); - sum += val; - } - - cmc_assert_equals(size_t, 10450, sum); - - s_free(s); - }); - - CMC_CREATE_TEST(PFX##_iter_rewind(), { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - struct stack_iter it = s_iter_end(s); - - cmc_assert(!s_iter_rewind(&it, 1)); - - for (size_t i = 0; i <= 1000; i++) - s_push(s, i); - - it = s_iter_end(s); - - cmc_assert(!s_iter_rewind(&it, 0)); - cmc_assert(!s_iter_rewind(&it, s->count)); - - size_t sum = 0; - for (it = s_iter_end(s);;) - { - sum += s_iter_value(&it); - - if (!s_iter_rewind(&it, 2)) - break; - } - - cmc_assert_equals(size_t, 250500, sum); - - s_iter_to_end(&it); - cmc_assert(s_iter_rewind(&it, s->count - 1)); - - // sum (0, 10, 20, ..., 90, 100) - sum = 0; - it = s_iter_end(s); - for (size_t val = s_iter_value(&it); val < 100; s_iter_rewind(&it, 10)) - { - val = s_iter_value(&it); - sum += val; - } - - cmc_assert_equals(size_t, 550, sum); - - s_free(s); - }); - - CMC_CREATE_TEST(PFX##_iter_go_to(), { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - struct stack_iter it = s_iter_end(s); - cmc_assert(!s_iter_go_to(&it, 0)); - - it = s_iter_start(s); - cmc_assert(!s_iter_go_to(&it, 0)); - - for (size_t i = 1001; i > 0; i--) - s_push(s, i - 1); - - it = s_iter_start(s); - - size_t sum = 0; - for (size_t i = 0; i < 1001; i++) - { - s_iter_go_to(&it, i); - - sum += s_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - for (size_t i = 1001; i > 0; i--) - { - cmc_assert(s_iter_go_to(&it, i - 1)); - - sum += s_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - for (size_t i = 1000; i > 0; i -= 100) - { - cmc_assert(s_iter_go_to(&it, 1000 - i)); - cmc_assert_equals(size_t, i, s_iter_index(&it)); - - sum += s_iter_value(&it); - } - - cmc_assert_equals(size_t, 5500, sum); - - s_free(s); - }); - - CMC_CREATE_TEST(PFX##_iter_value(), { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - struct stack_iter it = s_iter_end(s); - - cmc_assert_equals(size_t, (size_t){ 0 }, s_iter_value(&it)); - - cmc_assert(s_push(s, 10)); - - it = s_iter_start(s); - - cmc_assert_equals(size_t, 10, s_iter_value(&it)); - - s_free(s); - }); - - CMC_CREATE_TEST(PFX##_iter_rvalue(), { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - struct stack_iter it = s_iter_end(s); - - cmc_assert_equals(ptr, NULL, s_iter_rvalue(&it)); - - cmc_assert(s_push(s, 10)); - - it = s_iter_start(s); - - cmc_assert_not_equals(ptr, NULL, s_iter_rvalue(&it)); - cmc_assert_equals(size_t, 10, *s_iter_rvalue(&it)); - - s_free(s); - }); - - CMC_CREATE_TEST(PFX##_iter_index(), { - struct stack *s = s_new(100, s_fval); - - cmc_assert_not_equals(ptr, NULL, s); - - for (size_t i = 0; i <= 1000; i++) - s_push(s, i); - - struct stack_iter it = s_iter_start(s); - - for (size_t i = 0; i < 1001; i++) - { - cmc_assert_equals(size_t, i, s_iter_index(&it)); - s_iter_next(&it); - } - - it = s_iter_end(s); - for (size_t i = 1001; i > 0; i--) - { - cmc_assert_equals(size_t, i - 1, s_iter_index(&it)); - s_iter_prev(&it); - } - - s_free(s); - }); -}); - -#ifdef CMC_TEST_MAIN -int main(void) -{ - int result = CMCStack() + CMCStackIter(); - - printf(" +---------------------------------------------------------------+"); - printf("\n"); - printf(" | CMCStack Suit : %-48s |\n", result == 0 ? "PASSED" : "FAILED"); - printf(" +---------------------------------------------------------------+"); - printf("\n\n\n"); - - return result; -} -#endif - -#endif /* CMC_TESTS_UNT_CMC_STACK_H */ diff --git a/tests/unt/unt_cmc_treemap.h b/tests/unt/unt_cmc_treemap.h deleted file mode 100644 index 250133e..0000000 --- a/tests/unt/unt_cmc_treemap.h +++ /dev/null @@ -1,670 +0,0 @@ -#ifndef CMC_TESTS_UNT_CMC_TREEMAP_H -#define CMC_TESTS_UNT_CMC_TREEMAP_H - -#include "utl.h" - -#include "tst_cmc_treemap.h" - -struct treemap_fkey *tm_fkey = &(struct treemap_fkey){ - .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp -}; - -struct treemap_fval *tm_fval = &(struct treemap_fval){ - .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp -}; - -CMC_CREATE_UNIT(CMCTreeMap, true, { - CMC_CREATE_TEST(new, { - struct treemap *map = tm_new(tm_fkey, tm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - tm_free(map); - }); - - CMC_CREATE_TEST(clear[count], { - struct treemap *map = tm_new(tm_fkey, tm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 0; i < 50; i++) - tm_insert(map, i, i); - - cmc_assert_equals(size_t, 50, tm_count(map)); - - tm_clear(map); - - cmc_assert_equals(size_t, 0, tm_count(map)); - cmc_assert_equals(ptr, NULL, map->root); - - tm_free(map); - }); - - CMC_CREATE_TEST(flags, { - struct treemap *map = tm_new(tm_fkey, tm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map)); - - // clear - map->flag = CMC_FLAG_ERROR; - tm_clear(map); - cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map)); - - // insert - map->flag = CMC_FLAG_ERROR; - cmc_assert(tm_insert(map, 1, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map)); - - cmc_assert(!tm_insert(map, 1, 2)); - cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, tm_flag(map)); - - // update - cmc_assert(!tm_update(map, 2, 2, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, tm_flag(map)); - - cmc_assert(tm_update(map, 1, 2, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map)); - - // remove - cmc_assert(!tm_remove(map, 2, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, tm_flag(map)); - - cmc_assert(tm_remove(map, 1, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map)); - - cmc_assert(!tm_remove(map, 1, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, tm_flag(map)); - - // max min - map->flag = CMC_FLAG_ERROR; - cmc_assert(!tm_max(map, NULL, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, tm_flag(map)); - - map->flag = CMC_FLAG_ERROR; - cmc_assert(!tm_min(map, NULL, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, tm_flag(map)); - - cmc_assert(tm_insert(map, 1, 1)); - map->flag = CMC_FLAG_ERROR; - cmc_assert(tm_max(map, NULL, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map)); - - map->flag = CMC_FLAG_ERROR; - cmc_assert(tm_min(map, NULL, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map)); - - // get get_ref - tm_get(map, 2); - cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, tm_flag(map)); - - tm_get(map, 1); - cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map)); - - tm_get_ref(map, 2); - cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, tm_flag(map)); - - tm_get_ref(map, 1); - cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map)); - - cmc_assert(tm_remove(map, 1, NULL)); - map->flag = CMC_FLAG_ERROR; - tm_get(map, 1); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, tm_flag(map)); - - map->flag = CMC_FLAG_ERROR; - tm_get_ref(map, 1); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, tm_flag(map)); - - for (size_t i = 0; i < 100; i++) - cmc_assert(tm_insert(map, i, i)); - - // copy_of - map->flag = CMC_FLAG_ERROR; - struct treemap *map2 = tm_copy_of(map); - cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map2)); - - // equals - map->flag = CMC_FLAG_ERROR; - map2->flag = CMC_FLAG_ERROR; - cmc_assert(tm_equals(map, map2)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map2)); - - tm_free(map); - tm_free(map2); - }); - - CMC_CREATE_TEST(callbacks, { - struct treemap *map = tm_new_custom(tm_fkey, tm_fval, NULL, callbacks); - - cmc_assert_not_equals(ptr, NULL, map); - - total_create = 0; - total_read = 0; - total_update = 0; - total_delete = 0; - total_resize = 0; - - cmc_assert(tm_insert(map, 1, 10)); - cmc_assert_equals(int32_t, 1, total_create); - - cmc_assert(tm_update(map, 1, 2, NULL)); - cmc_assert_equals(int32_t, 1, total_update); - - cmc_assert(tm_remove(map, 1, NULL)); - cmc_assert_equals(int32_t, 1, total_delete); - - cmc_assert(tm_insert(map, 1, 2)); - cmc_assert_equals(int32_t, 2, total_create); - - cmc_assert(tm_max(map, NULL, NULL)); - cmc_assert_equals(int32_t, 1, total_read); - - cmc_assert(tm_min(map, NULL, NULL)); - cmc_assert_equals(int32_t, 2, total_read); - - cmc_assert_equals(size_t, 2, tm_get(map, 1)); - cmc_assert_equals(int32_t, 3, total_read); - - cmc_assert_not_equals(ptr, NULL, tm_get_ref(map, 1)); - cmc_assert_equals(int32_t, 4, total_read); - - cmc_assert(tm_contains(map, 1)); - cmc_assert_equals(int32_t, 5, total_read); - - cmc_assert_equals(int32_t, 2, total_create); - cmc_assert_equals(int32_t, 5, total_read); - cmc_assert_equals(int32_t, 1, total_update); - cmc_assert_equals(int32_t, 1, total_delete); - cmc_assert_equals(int32_t, 0, total_resize); - - tm_customize(map, NULL, NULL); - - tm_clear(map); - cmc_assert(tm_insert(map, 1, 10)); - cmc_assert(tm_update(map, 1, 2, NULL)); - cmc_assert(tm_remove(map, 1, NULL)); - cmc_assert(tm_insert(map, 1, 2)); - cmc_assert(tm_max(map, NULL, NULL)); - cmc_assert(tm_min(map, NULL, NULL)); - cmc_assert_equals(size_t, 2, tm_get(map, 1)); - cmc_assert_not_equals(ptr, NULL, tm_get_ref(map, 1)); - cmc_assert(tm_contains(map, 1)); - - cmc_assert_equals(int32_t, 2, total_create); - cmc_assert_equals(int32_t, 5, total_read); - cmc_assert_equals(int32_t, 1, total_update); - cmc_assert_equals(int32_t, 1, total_delete); - cmc_assert_equals(int32_t, 0, total_resize); - - cmc_assert_equals(ptr, NULL, map->callbacks); - - total_create = 0; - total_read = 0; - total_update = 0; - total_delete = 0; - total_resize = 0; - - tm_free(map); - }); -}); - -CMC_CREATE_UNIT(CMCTreeMapIter, true, { - CMC_CREATE_TEST(PFX##_iter_start(), { - struct treemap *map = tm_new(tm_fkey, tm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct treemap_iter it = tm_iter_start(map); - - cmc_assert_equals(ptr, map, it.target); - cmc_assert_equals(ptr, NULL, it.cursor); - cmc_assert_equals(ptr, NULL, it.first); - cmc_assert_equals(ptr, NULL, it.last); - cmc_assert_equals(size_t, 0, it.index); - cmc_assert_equals(bool, true, it.start); - cmc_assert_equals(bool, true, it.end); - - cmc_assert(tm_iter_at_start(&it)); - cmc_assert(tm_iter_at_end(&it)); - - cmc_assert(tm_insert(map, 1, 1)); - cmc_assert(tm_insert(map, 2, 2)); - cmc_assert(tm_insert(map, 3, 3)); - - it = tm_iter_start(map); - - cmc_assert_equals(size_t, 0, it.index); - - cmc_assert_equals(size_t, 1, it.cursor->key); - cmc_assert_equals(size_t, 1, it.first->key); - cmc_assert_equals(size_t, 3, it.last->key); - cmc_assert_equals(bool, false, it.end); - - tm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_end(), { - struct treemap *map = tm_new(tm_fkey, tm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct treemap_iter it = tm_iter_end(map); - - cmc_assert_equals(ptr, map, it.target); - cmc_assert_equals(ptr, NULL, it.cursor); - cmc_assert_equals(ptr, NULL, it.first); - cmc_assert_equals(ptr, NULL, it.last); - cmc_assert_equals(size_t, 0, it.index); - cmc_assert_equals(bool, true, it.start); - cmc_assert_equals(bool, true, it.end); - - cmc_assert(tm_iter_at_start(&it)); - cmc_assert(tm_iter_at_end(&it)); - - cmc_assert(tm_insert(map, 1, 1)); - cmc_assert(tm_insert(map, 2, 2)); - cmc_assert(tm_insert(map, 3, 3)); - - it = tm_iter_end(map); - - cmc_assert_equals(size_t, map->count - 1, it.index); - - cmc_assert_equals(size_t, 3, it.cursor->key); - cmc_assert_equals(size_t, 1, it.first->key); - cmc_assert_equals(size_t, 3, it.last->key); - cmc_assert_equals(bool, false, it.start); - - tm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_at_start(), { - struct treemap *map = tm_new(tm_fkey, tm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct treemap_iter it = tm_iter_start(map); - - // Empty checks - cmc_assert(tm_iter_at_start(&it)); - it = tm_iter_end(map); - cmc_assert(tm_iter_at_start(&it)); - - // Non-empty checks - cmc_assert(tm_insert(map, 1, 1)); - cmc_assert(tm_insert(map, 2, 2)); - it = tm_iter_end(map); - cmc_assert(!tm_iter_at_start(&it)); - it = tm_iter_start(map); - cmc_assert(tm_iter_at_start(&it)); - - tm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_at_end(), { - struct treemap *map = tm_new(tm_fkey, tm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct treemap_iter it = tm_iter_start(map); - - // Empty check - cmc_assert(tm_iter_at_end(&it)); - it = tm_iter_end(map); - cmc_assert(tm_iter_at_end(&it)); - - // Non-empty checks - cmc_assert(tm_insert(map, 1, 1)); - cmc_assert(tm_insert(map, 2, 2)); - it = tm_iter_end(map); - cmc_assert(tm_iter_at_end(&it)); - it = tm_iter_start(map); - cmc_assert(!tm_iter_at_end(&it)); - - tm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_to_start(), { - struct treemap *map = tm_new(tm_fkey, tm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct treemap_iter it = tm_iter_start(map); - - cmc_assert(!tm_iter_to_start(&it)); - - for (size_t i = 1; i <= 100; i++) - tm_insert(map, i, i); - - cmc_assert_equals(size_t, 100, map->count); - - it = tm_iter_end(map); - - cmc_assert(!tm_iter_at_start(&it)); - cmc_assert(tm_iter_at_end(&it)); - - cmc_assert_equals(size_t, 100, tm_iter_value(&it)); - - cmc_assert(tm_iter_to_start(&it)); - - cmc_assert(tm_iter_at_start(&it)); - cmc_assert(!tm_iter_at_end(&it)); - - cmc_assert_equals(size_t, 1, tm_iter_value(&it)); - - tm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_to_end(), { - struct treemap *map = tm_new(tm_fkey, tm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct treemap_iter it = tm_iter_end(map); - - cmc_assert(!tm_iter_to_end(&it)); - - for (size_t i = 1; i <= 100; i++) - tm_insert(map, i, i); - - it = tm_iter_start(map); - - cmc_assert(tm_iter_at_start(&it)); - cmc_assert(!tm_iter_at_end(&it)); - - cmc_assert_equals(size_t, 1, tm_iter_value(&it)); - - cmc_assert(tm_iter_to_end(&it)); - - cmc_assert(!tm_iter_at_start(&it)); - cmc_assert(tm_iter_at_end(&it)); - - cmc_assert_equals(size_t, 100, tm_iter_value(&it)); - - tm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_next(), { - struct treemap *map = tm_new(tm_fkey, tm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct treemap_iter it = tm_iter_start(map); - - cmc_assert(!tm_iter_next(&it)); - - for (size_t i = 1; i <= 1000; i++) - tm_insert(map, i, i); - - size_t sum = 0; - for (it = tm_iter_start(map); !tm_iter_at_end(&it); tm_iter_next(&it)) - { - sum += tm_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - - tm_iter_to_start(&it); - do - { - sum += tm_iter_value(&it); - } while (tm_iter_next(&it)); - - cmc_assert_equals(size_t, 500500, sum); - - tm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_prev(), { - struct treemap *map = tm_new(tm_fkey, tm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct treemap_iter it = tm_iter_end(map); - - cmc_assert(!tm_iter_prev(&it)); - - for (size_t i = 1; i <= 1000; i++) - tm_insert(map, i, i); - - size_t sum = 0; - for (it = tm_iter_end(map); !tm_iter_at_start(&it); tm_iter_prev(&it)) - { - sum += tm_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - - tm_iter_to_end(&it); - do - { - sum += tm_iter_value(&it); - } while (tm_iter_prev(&it)); - - cmc_assert_equals(size_t, 500500, sum); - - tm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_advance(), { - struct treemap *map = tm_new(tm_fkey, tm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct treemap_iter it = tm_iter_start(map); - - cmc_assert(!tm_iter_advance(&it, 1)); - - for (size_t i = 0; i <= 1000; i++) - tm_insert(map, i, i); - - it = tm_iter_start(map); - - cmc_assert(!tm_iter_advance(&it, 0)); - cmc_assert(!tm_iter_advance(&it, map->count)); - - size_t sum = 0; - for (it = tm_iter_start(map);;) - { - sum += tm_iter_value(&it); - - if (!tm_iter_advance(&it, 2)) - break; - } - - cmc_assert_equals(size_t, 250500, sum); - - tm_iter_to_start(&it); - cmc_assert(tm_iter_advance(&it, map->count - 1)); - - tm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_rewind(), { - struct treemap *map = tm_new(tm_fkey, tm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct treemap_iter it = tm_iter_end(map); - - cmc_assert(!tm_iter_rewind(&it, 1)); - - for (size_t i = 0; i <= 1000; i++) - tm_insert(map, i, i); - - it = tm_iter_end(map); - - cmc_assert(!tm_iter_rewind(&it, 0)); - cmc_assert(!tm_iter_rewind(&it, map->count)); - - size_t sum = 0; - for (it = tm_iter_end(map);;) - { - sum += tm_iter_value(&it); - - if (!tm_iter_rewind(&it, 2)) - break; - } - - cmc_assert_equals(size_t, 250500, sum); - - tm_iter_to_end(&it); - cmc_assert(tm_iter_rewind(&it, map->count - 1)); - - tm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_go_to(), { - struct treemap *map = tm_new(tm_fkey, tm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct treemap_iter it = tm_iter_end(map); - cmc_assert(!tm_iter_go_to(&it, 0)); - - it = tm_iter_start(map); - cmc_assert(!tm_iter_go_to(&it, 0)); - - for (size_t i = 0; i <= 1000; i++) - tm_insert(map, i, i); - - it = tm_iter_start(map); - - size_t sum = 0; - for (size_t i = 0; i < 1001; i++) - { - tm_iter_go_to(&it, i); - - sum += tm_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - for (size_t i = 1001; i > 0; i--) - { - cmc_assert(tm_iter_go_to(&it, i - 1)); - - sum += tm_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - for (size_t i = 0; i < 1001; i += 100) - { - cmc_assert(tm_iter_go_to(&it, i)); - cmc_assert_equals(size_t, i, tm_iter_index(&it)); - - sum += tm_iter_value(&it); - } - - cmc_assert_equals(size_t, 5500, sum); - - tm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_key(), { - struct treemap *map = tm_new(tm_fkey, tm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct treemap_iter it = tm_iter_end(map); - - cmc_assert_equals(size_t, (size_t){ 0 }, tm_iter_key(&it)); - - cmc_assert(tm_insert(map, 10, 10)); - - it = tm_iter_start(map); - - cmc_assert_equals(size_t, 10, tm_iter_key(&it)); - - tm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_value(), { - struct treemap *map = tm_new(tm_fkey, tm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct treemap_iter it = tm_iter_end(map); - - cmc_assert_equals(size_t, (size_t){ 0 }, tm_iter_value(&it)); - - cmc_assert(tm_insert(map, 10, 10)); - - it = tm_iter_start(map); - - cmc_assert_equals(size_t, 10, tm_iter_value(&it)); - - tm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_rvalue(), { - struct treemap *map = tm_new(tm_fkey, tm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - struct treemap_iter it = tm_iter_end(map); - - cmc_assert_equals(ptr, NULL, tm_iter_rvalue(&it)); - - cmc_assert(tm_insert(map, 10, 10)); - - it = tm_iter_start(map); - - cmc_assert_not_equals(ptr, NULL, tm_iter_rvalue(&it)); - cmc_assert_equals(size_t, 10, *tm_iter_rvalue(&it)); - - tm_free(map); - }); - - CMC_CREATE_TEST(PFX##_iter_index(), { - struct treemap *map = tm_new(tm_fkey, tm_fval); - - cmc_assert_not_equals(ptr, NULL, map); - - for (size_t i = 0; i <= 1000; i++) - tm_insert(map, i, i); - - struct treemap_iter it = tm_iter_start(map); - - for (size_t i = 0; i < 1001; i++) - { - cmc_assert_equals(size_t, i, tm_iter_index(&it)); - tm_iter_next(&it); - } - - it = tm_iter_end(map); - for (size_t i = 1001; i > 0; i--) - { - cmc_assert_equals(size_t, i - 1, tm_iter_index(&it)); - tm_iter_prev(&it); - } - - tm_free(map); - }); -}); - -#ifdef CMC_TEST_MAIN -int main(void) -{ - int result = CMCTreeMap() + CMCTreeMapIter(); - - printf(" +---------------------------------------------------------------+"); - printf("\n"); - printf(" | CMCTreeMap Suit : %-46s |\n", result == 0 ? "PASSED" : "FAILED"); - printf(" +---------------------------------------------------------------+"); - printf("\n\n\n"); - - return result; -} -#endif - -#endif /* CMC_TESTS_UNT_CMC_TREEMAP_H */ diff --git a/tests/unt/unt_cmc_treeset.h b/tests/unt/unt_cmc_treeset.h deleted file mode 100644 index afee067..0000000 --- a/tests/unt/unt_cmc_treeset.h +++ /dev/null @@ -1,585 +0,0 @@ -#ifndef CMC_TESTS_UNT_CMC_TREESET_H -#define CMC_TESTS_UNT_CMC_TREESET_H - -#include "utl.h" - -#include "tst_cmc_treeset.h" - -struct treeset_fval *ts_fval = &(struct treeset_fval){ - .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp -}; - -CMC_CREATE_UNIT(CMCTreeSet, true, { - CMC_CREATE_TEST(new, { - struct treeset *set = ts_new(ts_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - ts_free(set); - }); - - CMC_CREATE_TEST(clear[count], { - struct treeset *set = ts_new(ts_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - for (size_t i = 0; i < 50; i++) - ts_insert(set, i); - - cmc_assert_equals(size_t, 50, ts_count(set)); - - ts_clear(set); - - cmc_assert_equals(size_t, 0, ts_count(set)); - cmc_assert_equals(ptr, NULL, set->root); - - ts_free(set); - }); - - CMC_CREATE_TEST(flags, { - struct treeset *set = ts_new(ts_fval); - - cmc_assert_not_equals(ptr, NULL, set); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ts_flag(set)); - - // clear - set->flag = CMC_FLAG_ERROR; - ts_clear(set); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ts_flag(set)); - - // insert - set->flag = CMC_FLAG_ERROR; - cmc_assert(ts_insert(set, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ts_flag(set)); - - cmc_assert(!ts_insert(set, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, ts_flag(set)); - - // remove - cmc_assert(!ts_remove(set, 2)); - cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, ts_flag(set)); - - cmc_assert(ts_remove(set, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ts_flag(set)); - - cmc_assert(!ts_remove(set, 1)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ts_flag(set)); - - // max min - set->flag = CMC_FLAG_ERROR; - cmc_assert(!ts_max(set, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ts_flag(set)); - - set->flag = CMC_FLAG_ERROR; - cmc_assert(!ts_min(set, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ts_flag(set)); - - cmc_assert(ts_insert(set, 1)); - set->flag = CMC_FLAG_ERROR; - cmc_assert(ts_max(set, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ts_flag(set)); - - set->flag = CMC_FLAG_ERROR; - cmc_assert(ts_min(set, NULL)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ts_flag(set)); - - // copy_of - set->flag = CMC_FLAG_ERROR; - struct treeset *set2 = ts_copy_of(set); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ts_flag(set)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ts_flag(set2)); - - // equals - set->flag = CMC_FLAG_ERROR; - set2->flag = CMC_FLAG_ERROR; - cmc_assert(ts_equals(set, set2)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ts_flag(set)); - cmc_assert_equals(int32_t, CMC_FLAG_OK, ts_flag(set2)); - - ts_free(set); - ts_free(set2); - }); - - CMC_CREATE_TEST(callbacks, { - struct treeset *set = ts_new_custom(ts_fval, NULL, callbacks); - - cmc_assert_not_equals(ptr, NULL, set); - - total_create = 0; - total_read = 0; - total_update = 0; - total_delete = 0; - total_resize = 0; - - cmc_assert(ts_insert(set, 10)); - cmc_assert_equals(int32_t, 1, total_create); - - cmc_assert(ts_remove(set, 10)); - cmc_assert_equals(int32_t, 1, total_delete); - - cmc_assert(ts_insert(set, 1)); - cmc_assert_equals(int32_t, 2, total_create); - - cmc_assert(ts_max(set, NULL)); - cmc_assert_equals(int32_t, 1, total_read); - - cmc_assert(ts_min(set, NULL)); - cmc_assert_equals(int32_t, 2, total_read); - - cmc_assert(ts_contains(set, 1)); - cmc_assert_equals(int32_t, 3, total_read); - - cmc_assert_equals(int32_t, 2, total_create); - cmc_assert_equals(int32_t, 3, total_read); - cmc_assert_equals(int32_t, 0, total_update); - cmc_assert_equals(int32_t, 1, total_delete); - cmc_assert_equals(int32_t, 0, total_resize); - - ts_customize(set, NULL, NULL); - - ts_clear(set); - cmc_assert(ts_insert(set, 10)); - cmc_assert(ts_remove(set, 10)); - cmc_assert(ts_insert(set, 1)); - cmc_assert(ts_max(set, NULL)); - cmc_assert(ts_min(set, NULL)); - cmc_assert(ts_contains(set, 1)); - - cmc_assert_equals(int32_t, 2, total_create); - cmc_assert_equals(int32_t, 3, total_read); - cmc_assert_equals(int32_t, 0, total_update); - cmc_assert_equals(int32_t, 1, total_delete); - cmc_assert_equals(int32_t, 0, total_resize); - - cmc_assert_equals(ptr, NULL, set->callbacks); - - total_create = 0; - total_read = 0; - total_update = 0; - total_delete = 0; - total_resize = 0; - - ts_free(set); - }); -}); - -CMC_CREATE_UNIT(CMCTreeSetIter, true, { - CMC_CREATE_TEST(PFX##_iter_start(), { - struct treeset *set = ts_new(ts_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - struct treeset_iter it = ts_iter_start(set); - - cmc_assert_equals(ptr, set, it.target); - cmc_assert_equals(ptr, NULL, it.cursor); - cmc_assert_equals(ptr, NULL, it.first); - cmc_assert_equals(ptr, NULL, it.last); - cmc_assert_equals(size_t, 0, it.index); - cmc_assert_equals(bool, true, it.start); - cmc_assert_equals(bool, true, it.end); - - cmc_assert(ts_iter_at_start(&it)); - cmc_assert(ts_iter_at_end(&it)); - - cmc_assert(ts_insert(set, 1)); - cmc_assert(ts_insert(set, 2)); - cmc_assert(ts_insert(set, 3)); - - it = ts_iter_start(set); - - cmc_assert_equals(size_t, 0, it.index); - - cmc_assert_equals(size_t, 1, it.cursor->value); - cmc_assert_equals(size_t, 1, it.first->value); - cmc_assert_equals(size_t, 3, it.last->value); - cmc_assert_equals(bool, false, it.end); - - ts_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_end(), { - struct treeset *set = ts_new(ts_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - struct treeset_iter it = ts_iter_end(set); - - cmc_assert_equals(ptr, set, it.target); - cmc_assert_equals(ptr, NULL, it.cursor); - cmc_assert_equals(ptr, NULL, it.first); - cmc_assert_equals(ptr, NULL, it.last); - cmc_assert_equals(size_t, 0, it.index); - cmc_assert_equals(bool, true, it.start); - cmc_assert_equals(bool, true, it.end); - - cmc_assert(ts_iter_at_start(&it)); - cmc_assert(ts_iter_at_end(&it)); - - cmc_assert(ts_insert(set, 1)); - cmc_assert(ts_insert(set, 2)); - cmc_assert(ts_insert(set, 3)); - - it = ts_iter_end(set); - - cmc_assert_equals(size_t, set->count - 1, it.index); - - cmc_assert_equals(size_t, 3, it.cursor->value); - cmc_assert_equals(size_t, 1, it.first->value); - cmc_assert_equals(size_t, 3, it.last->value); - cmc_assert_equals(bool, false, it.start); - - ts_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_at_start(), { - struct treeset *set = ts_new(ts_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - struct treeset_iter it = ts_iter_start(set); - - // Empty checks - cmc_assert(ts_iter_at_start(&it)); - it = ts_iter_end(set); - cmc_assert(ts_iter_at_start(&it)); - - // Non-empty checks - cmc_assert(ts_insert(set, 1)); - cmc_assert(ts_insert(set, 2)); - it = ts_iter_end(set); - cmc_assert(!ts_iter_at_start(&it)); - it = ts_iter_start(set); - cmc_assert(ts_iter_at_start(&it)); - - ts_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_at_end(), { - struct treeset *set = ts_new(ts_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - struct treeset_iter it = ts_iter_start(set); - - // Empty check - cmc_assert(ts_iter_at_end(&it)); - it = ts_iter_end(set); - cmc_assert(ts_iter_at_end(&it)); - - // Non-empty checks - cmc_assert(ts_insert(set, 1)); - cmc_assert(ts_insert(set, 2)); - it = ts_iter_end(set); - cmc_assert(ts_iter_at_end(&it)); - it = ts_iter_start(set); - cmc_assert(!ts_iter_at_end(&it)); - - ts_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_to_start(), { - struct treeset *set = ts_new(ts_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - struct treeset_iter it = ts_iter_start(set); - - cmc_assert(!ts_iter_to_start(&it)); - - for (size_t i = 1; i <= 100; i++) - ts_insert(set, i); - - cmc_assert_equals(size_t, 100, set->count); - - it = ts_iter_end(set); - - cmc_assert(!ts_iter_at_start(&it)); - cmc_assert(ts_iter_at_end(&it)); - - cmc_assert_equals(size_t, 100, ts_iter_value(&it)); - - cmc_assert(ts_iter_to_start(&it)); - - cmc_assert(ts_iter_at_start(&it)); - cmc_assert(!ts_iter_at_end(&it)); - - cmc_assert_equals(size_t, 1, ts_iter_value(&it)); - - ts_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_to_end(), { - struct treeset *set = ts_new(ts_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - struct treeset_iter it = ts_iter_end(set); - - cmc_assert(!ts_iter_to_end(&it)); - - for (size_t i = 1; i <= 100; i++) - ts_insert(set, i); - - it = ts_iter_start(set); - - cmc_assert(ts_iter_at_start(&it)); - cmc_assert(!ts_iter_at_end(&it)); - - cmc_assert_equals(size_t, 1, ts_iter_value(&it)); - - cmc_assert(ts_iter_to_end(&it)); - - cmc_assert(!ts_iter_at_start(&it)); - cmc_assert(ts_iter_at_end(&it)); - - cmc_assert_equals(size_t, 100, ts_iter_value(&it)); - - ts_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_next(), { - struct treeset *set = ts_new(ts_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - struct treeset_iter it = ts_iter_start(set); - - cmc_assert(!ts_iter_next(&it)); - - for (size_t i = 1; i <= 1000; i++) - ts_insert(set, i); - - size_t sum = 0; - for (it = ts_iter_start(set); !ts_iter_at_end(&it); ts_iter_next(&it)) - { - sum += ts_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - - ts_iter_to_start(&it); - do - { - sum += ts_iter_value(&it); - } while (ts_iter_next(&it)); - - cmc_assert_equals(size_t, 500500, sum); - - ts_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_prev(), { - struct treeset *set = ts_new(ts_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - struct treeset_iter it = ts_iter_end(set); - - cmc_assert(!ts_iter_prev(&it)); - - for (size_t i = 1; i <= 1000; i++) - ts_insert(set, i); - - size_t sum = 0; - for (it = ts_iter_end(set); !ts_iter_at_start(&it); ts_iter_prev(&it)) - { - sum += ts_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - - ts_iter_to_end(&it); - do - { - sum += ts_iter_value(&it); - } while (ts_iter_prev(&it)); - - cmc_assert_equals(size_t, 500500, sum); - - ts_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_advance(), { - struct treeset *set = ts_new(ts_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - struct treeset_iter it = ts_iter_start(set); - - cmc_assert(!ts_iter_advance(&it, 1)); - - for (size_t i = 0; i <= 1000; i++) - ts_insert(set, i); - - it = ts_iter_start(set); - - cmc_assert(!ts_iter_advance(&it, 0)); - cmc_assert(!ts_iter_advance(&it, set->count)); - - size_t sum = 0; - for (it = ts_iter_start(set);;) - { - sum += ts_iter_value(&it); - - if (!ts_iter_advance(&it, 2)) - break; - } - - cmc_assert_equals(size_t, 250500, sum); - - ts_iter_to_start(&it); - cmc_assert(ts_iter_advance(&it, set->count - 1)); - - ts_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_rewind(), { - struct treeset *set = ts_new(ts_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - struct treeset_iter it = ts_iter_end(set); - - cmc_assert(!ts_iter_rewind(&it, 1)); - - for (size_t i = 0; i <= 1000; i++) - ts_insert(set, i); - - it = ts_iter_end(set); - - cmc_assert(!ts_iter_rewind(&it, 0)); - cmc_assert(!ts_iter_rewind(&it, set->count)); - - size_t sum = 0; - for (it = ts_iter_end(set);;) - { - sum += ts_iter_value(&it); - - if (!ts_iter_rewind(&it, 2)) - break; - } - - cmc_assert_equals(size_t, 250500, sum); - - ts_iter_to_end(&it); - cmc_assert(ts_iter_rewind(&it, set->count - 1)); - - ts_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_go_to(), { - struct treeset *set = ts_new(ts_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - struct treeset_iter it = ts_iter_end(set); - cmc_assert(!ts_iter_go_to(&it, 0)); - - it = ts_iter_start(set); - cmc_assert(!ts_iter_go_to(&it, 0)); - - for (size_t i = 0; i <= 1000; i++) - ts_insert(set, i); - - it = ts_iter_start(set); - - size_t sum = 0; - for (size_t i = 0; i < 1001; i++) - { - ts_iter_go_to(&it, i); - - sum += ts_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - for (size_t i = 1001; i > 0; i--) - { - cmc_assert(ts_iter_go_to(&it, i - 1)); - - sum += ts_iter_value(&it); - } - - cmc_assert_equals(size_t, 500500, sum); - - sum = 0; - for (size_t i = 0; i < 1001; i += 100) - { - cmc_assert(ts_iter_go_to(&it, i)); - cmc_assert_equals(size_t, i, ts_iter_index(&it)); - - sum += ts_iter_value(&it); - } - - cmc_assert_equals(size_t, 5500, sum); - - ts_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_value(), { - struct treeset *set = ts_new(ts_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - struct treeset_iter it = ts_iter_end(set); - - cmc_assert_equals(size_t, (size_t){ 0 }, ts_iter_value(&it)); - - cmc_assert(ts_insert(set, 10)); - - it = ts_iter_start(set); - - cmc_assert_equals(size_t, 10, ts_iter_value(&it)); - - ts_free(set); - }); - - CMC_CREATE_TEST(PFX##_iter_index(), { - struct treeset *set = ts_new(ts_fval); - - cmc_assert_not_equals(ptr, NULL, set); - - for (size_t i = 0; i <= 1000; i++) - ts_insert(set, i); - - struct treeset_iter it = ts_iter_start(set); - - for (size_t i = 0; i < 1001; i++) - { - cmc_assert_equals(size_t, i, ts_iter_index(&it)); - ts_iter_next(&it); - } - - it = ts_iter_end(set); - for (size_t i = 1001; i > 0; i--) - { - cmc_assert_equals(size_t, i - 1, ts_iter_index(&it)); - ts_iter_prev(&it); - } - - ts_free(set); - }); -}); - -#ifdef CMC_TEST_MAIN -int main(void) -{ - int result = CMCTreeSet() + CMCTreeSetIter(); - - printf(" +---------------------------------------------------------------+"); - printf("\n"); - printf(" | CMCTreeSet Suit : %-46s |\n", result == 0 ? "PASSED" : "FAILED"); - printf(" +---------------------------------------------------------------+"); - printf("\n\n\n"); - - return result; -} -#endif - -#endif /* CMC_TESTS_UNT_CMC_TREESET_H */ diff --git a/tests/unt/unt_utl_foreach.h b/tests/unt/unt_utl_foreach.h deleted file mode 100644 index 938ca13..0000000 --- a/tests/unt/unt_utl_foreach.h +++ /dev/null @@ -1,508 +0,0 @@ -#ifndef CMC_TESTS_UNT_UTL_FOREACH_H -#define CMC_TESTS_UNT_UTL_FOREACH_H - -#include "utl.h" - -#include "tst_cmc_bitset.h" -#include "tst_cmc_deque.h" -#include "tst_cmc_hashbidimap.h" -#include "tst_cmc_hashmap.h" -#include "tst_cmc_hashmultimap.h" -#include "tst_cmc_hashmultiset.h" -#include "tst_cmc_hashset.h" -#include "tst_cmc_heap.h" -#include "tst_cmc_intervalheap.h" -#include "tst_cmc_linkedlist.h" -#include "tst_cmc_list.h" -#include "tst_cmc_queue.h" -#include "tst_cmc_sortedlist.h" -#include "tst_cmc_stack.h" -#include "tst_cmc_treemap.h" -#include "tst_cmc_treeset.h" - -CMC_CREATE_UNIT(ForEach, true, { - // CMC_CREATE_TEST(CMC, { - // struct bitset *bs = bs_new(10000); - - // // WIP - - // bs_free(bs); - // }); - - CMC_CREATE_TEST(CMC, { - struct deque *d = d_new(10000, &(struct deque_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }); - - for (size_t i = 1; i <= 10000; i++) - d_push_back(d, i); - - size_t sum = 0; - CMC_FOREACH (d, deque, it, d) - { - sum += d_iter_value(&it); - } - cmc_assert_equals(size_t, 50005000, sum); - - sum = 0; - CMC_FOREACH_REV (d, deque, it, d) - { - sum += d_iter_value(&it); - } - cmc_assert_equals(size_t, 50005000, sum); - - d_free(d); - }); - - // CMC_CREATE_TEST(CMC, { - // struct hashbidimap *hbm = - // hbm_new(10000, 0.7, - // &(struct hashbidimap_fkey){ .cmp = cmc_size_cmp, - // .cpy = NULL, - // .str = cmc_size_str, - // .free = NULL, - // .hash = cmc_size_hash, - // .pri = cmc_size_cmp }, - // &(struct hashbidimap_fval){ .cmp = cmc_size_cmp, - // .cpy = NULL, - // .str = cmc_size_str, - // .free = NULL, - // .hash = cmc_size_hash, - // .pri = cmc_size_cmp }); - - // // WIP - - // hbm_free(hbm); - // }); - - CMC_CREATE_TEST(CMC, { - struct hashmap *hm = hm_new(10000, 0.6, - &(struct hashmap_fkey){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }, - &(struct hashmap_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }); - - for (size_t i = 1; i <= 10000; i++) - hm_insert(hm, i, i); - - size_t sumk = 0; - size_t sumv = 0; - CMC_FOREACH (hm, hashmap, it, hm) - { - sumk += hm_iter_key(&it); - sumv += hm_iter_value(&it); - } - cmc_assert_equals(size_t, 50005000, sumk); - cmc_assert_equals(size_t, 50005000, sumv); - - sumk = 0; - sumv = 0; - CMC_FOREACH_REV (hm, hashmap, it, hm) - { - sumk += hm_iter_key(&it); - sumv += hm_iter_value(&it); - } - cmc_assert_equals(size_t, 50005000, sumk); - cmc_assert_equals(size_t, 50005000, sumv); - - hm_free(hm); - }); - - CMC_CREATE_TEST(CMC, { - struct hashmultimap *hmm = hmm_new(10000, 0.6, - &(struct hashmultimap_fkey){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }, - &(struct hashmultimap_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }); - - for (size_t i = 1; i <= 10000; i++) - hmm_insert(hmm, i, i); - - size_t sumk = 0; - size_t sumv = 0; - CMC_FOREACH (hmm, hashmultimap, it, hmm) - { - sumk += hmm_iter_key(&it); - sumv += hmm_iter_value(&it); - } - cmc_assert_equals(size_t, 50005000, sumk); - cmc_assert_equals(size_t, 50005000, sumv); - - sumk = 0; - sumv = 0; - CMC_FOREACH_REV (hmm, hashmultimap, it, hmm) - { - sumk += hmm_iter_key(&it); - sumv += hmm_iter_value(&it); - } - cmc_assert_equals(size_t, 50005000, sumk); - cmc_assert_equals(size_t, 50005000, sumv); - - hmm_free(hmm); - }); - - CMC_CREATE_TEST(CMC, { - struct hashmultiset *hms = hms_new(10000, 0.6, - &(struct hashmultiset_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }); - - for (size_t i = 1; i <= 10000; i++) - hms_insert_many(hms, i, i); - - size_t sumk = 0; - size_t sumv = 0; - CMC_FOREACH (hms, hashmultiset, it, hms) - { - sumk += hms_iter_value(&it); - sumv += hms_iter_multiplicity(&it); - } - cmc_assert_equals(size_t, 50005000, sumk); - cmc_assert_equals(size_t, 50005000, sumv); - - sumk = 0; - sumv = 0; - CMC_FOREACH_REV (hms, hashmultiset, it, hms) - { - sumk += hms_iter_value(&it); - sumv += hms_iter_multiplicity(&it); - } - cmc_assert_equals(size_t, 50005000, sumk); - cmc_assert_equals(size_t, 50005000, sumv); - - hms_free(hms); - }); - - CMC_CREATE_TEST(CMC, { - struct hashset *hs = hs_new(10000, 0.6, - &(struct hashset_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }); - - for (size_t i = 1; i <= 10000; i++) - hs_insert(hs, i); - - size_t sumv = 0; - CMC_FOREACH (hs, hashset, it, hs) - { - sumv += hs_iter_value(&it); - } - cmc_assert_equals(size_t, 50005000, sumv); - - sumv = 0; - CMC_FOREACH_REV (hs, hashset, it, hs) - { - sumv += hs_iter_value(&it); - } - cmc_assert_equals(size_t, 50005000, sumv); - - hs_free(hs); - }); - - CMC_CREATE_TEST(CMC, { - struct heap *h = h_new(10000, CMC_MAX_HEAP, - &(struct heap_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }); - - for (size_t i = 1; i <= 10000; i++) - h_insert(h, i); - - size_t sumv = 0; - CMC_FOREACH (h, heap, it, h) - { - sumv += h_iter_value(&it); - } - cmc_assert_equals(size_t, 50005000, sumv); - - sumv = 0; - CMC_FOREACH_REV (h, heap, it, h) - { - sumv += h_iter_value(&it); - } - cmc_assert_equals(size_t, 50005000, sumv); - - h_free(h); - }); - - CMC_CREATE_TEST(CMC, { - struct intervalheap *ih = ih_new(10000, &(struct intervalheap_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }); - - for (size_t i = 1; i <= 10000; i++) - ih_insert(ih, i); - - size_t sumv = 0; - CMC_FOREACH (ih, intervalheap, it, ih) - { - sumv += ih_iter_value(&it); - } - cmc_assert_equals(size_t, 50005000, sumv); - - sumv = 0; - CMC_FOREACH_REV (ih, intervalheap, it, ih) - { - sumv += ih_iter_value(&it); - } - cmc_assert_equals(size_t, 50005000, sumv); - - ih_free(ih); - }); - - CMC_CREATE_TEST(CMC, { - struct linkedlist *ll = ll_new(&(struct linkedlist_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }); - - for (size_t i = 1; i <= 10000; i++) - ll_push_back(ll, i); - - size_t sumv = 0; - CMC_FOREACH (ll, linkedlist, it, ll) - { - sumv += ll_iter_value(&it); - } - cmc_assert_equals(size_t, 50005000, sumv); - - sumv = 0; - CMC_FOREACH_REV (ll, linkedlist, it, ll) - { - sumv += ll_iter_value(&it); - } - cmc_assert_equals(size_t, 50005000, sumv); - - ll_free(ll); - }); - - CMC_CREATE_TEST(CMC, { - struct list *l = l_new(10000, &(struct list_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }); - - for (size_t i = 1; i <= 10000; i++) - l_push_back(l, i); - - size_t sumv = 0; - CMC_FOREACH (l, list, it, l) - { - sumv += l_iter_value(&it); - } - cmc_assert_equals(size_t, 50005000, sumv); - - sumv = 0; - CMC_FOREACH_REV (l, list, it, l) - { - sumv += l_iter_value(&it); - } - cmc_assert_equals(size_t, 50005000, sumv); - - l_free(l); - }); - - CMC_CREATE_TEST(CMC, { - struct queue *q = q_new(10000, &(struct queue_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }); - - for (size_t i = 1; i <= 10000; i++) - q_enqueue(q, i); - - size_t sumv = 0; - CMC_FOREACH (q, queue, it, q) - { - sumv += q_iter_value(&it); - } - cmc_assert_equals(size_t, 50005000, sumv); - - sumv = 0; - CMC_FOREACH_REV (q, queue, it, q) - { - sumv += q_iter_value(&it); - } - cmc_assert_equals(size_t, 50005000, sumv); - - q_free(q); - }); - - CMC_CREATE_TEST(CMC, { - struct sortedlist *sl = sl_new(10000, &(struct sortedlist_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }); - - for (size_t i = 1; i <= 10000; i++) - sl_insert(sl, i); - - size_t sumv = 0; - CMC_FOREACH (sl, sortedlist, it, sl) - { - sumv += sl_iter_value(&it); - } - cmc_assert_equals(size_t, 50005000, sumv); - - sumv = 0; - CMC_FOREACH_REV (sl, sortedlist, it, sl) - { - sumv += sl_iter_value(&it); - } - cmc_assert_equals(size_t, 50005000, sumv); - - sl_free(sl); - }); - - CMC_CREATE_TEST(CMC, { - struct stack *s = s_new(10000, &(struct stack_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }); - - for (size_t i = 1; i <= 10000; i++) - s_push(s, i); - - size_t sumv = 0; - CMC_FOREACH (s, stack, it, s) - { - sumv += s_iter_value(&it); - } - cmc_assert_equals(size_t, 50005000, sumv); - - sumv = 0; - CMC_FOREACH_REV (s, stack, it, s) - { - sumv += s_iter_value(&it); - } - cmc_assert_equals(size_t, 50005000, sumv); - - s_free(s); - }); - - CMC_CREATE_TEST(CMC, { - struct treemap *tm = tm_new(&(struct treemap_fkey){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }, - &(struct treemap_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }); - - for (size_t i = 1; i <= 10000; i++) - tm_insert(tm, i, i); - - size_t sumk = 0; - size_t sumv = 0; - CMC_FOREACH (tm, treemap, it, tm) - { - sumk += tm_iter_key(&it); - sumv += tm_iter_value(&it); - } - cmc_assert_equals(size_t, 50005000, sumk); - cmc_assert_equals(size_t, 50005000, sumv); - - sumk = 0; - sumv = 0; - CMC_FOREACH_REV (tm, treemap, it, tm) - { - sumk += tm_iter_key(&it); - sumv += tm_iter_value(&it); - } - cmc_assert_equals(size_t, 50005000, sumk); - cmc_assert_equals(size_t, 50005000, sumv); - - tm_free(tm); - }); - - CMC_CREATE_TEST(CMC, { - struct treeset *ts = ts_new(&(struct treeset_fval){ .cmp = cmc_size_cmp, - .cpy = NULL, - .str = cmc_size_str, - .free = NULL, - .hash = cmc_size_hash, - .pri = cmc_size_cmp }); - - for (size_t i = 1; i <= 10000; i++) - ts_insert(ts, i); - - size_t sumv = 0; - CMC_FOREACH (ts, treeset, it, ts) - { - sumv += ts_iter_value(&it); - } - cmc_assert_equals(size_t, 50005000, sumv); - - sumv = 0; - CMC_FOREACH_REV (ts, treeset, it, ts) - { - sumv += ts_iter_value(&it); - } - cmc_assert_equals(size_t, 50005000, sumv); - - ts_free(ts); - }); -}); - -#ifdef CMC_TEST_MAIN -int main(void) -{ - int result = ForEach(); - - printf(" +---------------------------------------------------------------+"); - printf("\n"); - printf(" | ForEach Suit : %-46s |\n", result == 0 ? "PASSED" : "FAILED"); - printf(" +---------------------------------------------------------------+"); - printf("\n\n\n"); - - return result; -} -#endif - -#endif /* CMC_TESTS_UNT_UTL_FOREACH_H */ diff --git a/tests/unt/utl.h b/tests/unt/utl.h deleted file mode 100644 index 6078ead..0000000 --- a/tests/unt/utl.h +++ /dev/null @@ -1,171 +0,0 @@ -/* Utility file to be included in the unit tests */ -#ifndef CMC_TESTS_UTL -#define CMC_TESTS_UTL - -#include -#include -#include - -#include "cor_hashtable.h" -#include "utl_assert.h" -#include "utl_foreach.h" -#include "utl_futils.h" -#include "utl_test.h" - -size_t numhash(size_t a) -{ - return a; -} - -size_t hashcapminus1(size_t a) -{ - (void)a; - return cmc_hashtable_primes[0] - 1; -} - -size_t hashcapminus4(size_t a) -{ - (void)a; - return cmc_hashtable_primes[0] - 1; -} - -size_t hash0(size_t a) -{ - (void)a; - return 0; -} - -// counter ftab functions - -int32_t k_total_cmp = 0; -int32_t k_total_cpy = 0; -int32_t k_total_str = 0; -int32_t k_total_free = 0; -int32_t k_total_hash = 0; -int32_t k_total_pri = 0; - -int32_t v_total_cmp = 0; -int32_t v_total_cpy = 0; -int32_t v_total_str = 0; -int32_t v_total_free = 0; -int32_t v_total_hash = 0; -int32_t v_total_pri = 0; - -int k_c_cmp(size_t a, size_t b) -{ - k_total_cmp++; - return (a > b) - (a < b); -} - -size_t k_c_cpy(size_t a) -{ - k_total_cpy++; - return a; -} - -bool k_c_str(FILE *fptr, size_t a) -{ - k_total_str++; - return fprintf(fptr, "%" PRIuMAX " ", a) > 0; -} - -void k_c_free(size_t a) -{ - (void)a; - k_total_free++; -} - -size_t k_c_hash(size_t x) -{ - k_total_hash++; - x = ((x >> 16) ^ x) * 0x45d9f3b; - x = ((x >> 16) ^ x) * 0x45d9f3b; - x = (x >> 16) ^ x; - return x; -} - -int k_c_pri(size_t a, size_t b) -{ - k_total_pri++; - return (a > b) - (a < b); -} - -int v_c_cmp(size_t a, size_t b) -{ - v_total_cmp++; - return (a > b) - (a < b); -} - -size_t v_c_cpy(size_t a) -{ - v_total_cpy++; - return a; -} - -bool v_c_str(FILE *fptr, size_t a) -{ - v_total_str++; - return fprintf(fptr, "%" PRIuMAX " ", a) > 0; -} - -void v_c_free(size_t a) -{ - (void)a; - v_total_free++; -} - -size_t v_c_hash(size_t x) -{ - v_total_hash++; - x = ((x >> 16) ^ x) * 0x45d9f3b; - x = ((x >> 16) ^ x) * 0x45d9f3b; - x = (x >> 16) ^ x; - return x; -} - -int v_c_pri(size_t a, size_t b) -{ - v_total_pri++; - return (a > b) - (a < b); -} - -// callbacks - -int total_create = 0; -int total_read = 0; -int total_update = 0; -int total_delete = 0; -int total_resize = 0; - -void callback_create(void) -{ - total_create++; -} - -void callback_read(void) -{ - total_read++; -} - -void callback_update(void) -{ - total_update++; -} - -void callback_delete(void) -{ - total_delete++; -} - -void callback_resize(void) -{ - total_resize++; -} - -struct cmc_callbacks *callbacks = &(struct cmc_callbacks){ .create = callback_create, - .read = callback_read, - .update = callback_update, - .delete = callback_delete, - .resize = callback_resize }; - -#endif /* CMC_TESTS_UTL */