Files
mlib/tests/test-mrbtree.c
T
2020-01-04 15:41:06 +01:00

271 lines
7.8 KiB
C

/*
* Copyright (c) 2017-2020, Patrick Pelissier
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* + Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* + Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include "test-obj.h"
#include "m-string.h"
#include "m-rbtree.h"
static bool uint_in_str(unsigned int *u, FILE *f)
{
int n = fscanf(f, "%u", u);
return n == 1;
}
static bool uint_parse_str(unsigned int *u, const char str[], const char **endptr)
{
char *end;
*u = strtol(str, &end, 0);
if (endptr) { *endptr = (const char*) end; }
return (uintptr_t) end != (uintptr_t) str;
}
static void uint_out_str(FILE *f, unsigned int u)
{
fprintf(f, "%u", u);
}
static void uint_get_str(string_t str, unsigned int u, bool append)
{
(append ? string_cat_printf : string_printf) (str, "%u", u);
}
#include "coverage.h"
START_COVERAGE
RBTREE_DEF(rbtree_uint, unsigned int, M_OPEXTEND(M_DEFAULT_OPLIST, IN_STR(uint_in_str M_IPTR), OUT_STR(uint_out_str), GET_STR(uint_get_str), PARSE_STR(uint_parse_str M_IPTR)) )
END_COVERAGE
RBTREE_DEF(rbtree_float, float)
RBTREE_DEF(rbtree_mpz, testobj_t, TESTOBJ_OPLIST)
#define UINT_OPLIST RBTREE_OPLIST(rbtree_uint)
#define FLOAT_OP RBTREE_OPLIST(rbtree_float)
static void test_uint(void)
{
rbtree_uint_t tree, tree2, tree3;
rbtree_uint_init(tree);
assert (rbtree_uint_empty_p(tree));
rbtree_uint_init_set(tree2, tree);
assert (rbtree_uint_empty_p(tree2));
rbtree_uint_push(tree, 10);
rbtree_uint_push(tree, 5);
rbtree_uint_push(tree, 17);
rbtree_uint_push(tree, 3);
rbtree_uint_push(tree, 11);
assert(rbtree_uint_size(tree) == 5);
assert(rbtree_uint_empty_p(tree) == false);
const unsigned int tab[] = {3, 5, 10, 11, 17};
int k = 0;
for M_EACH(item, tree, UINT_OPLIST) {
assert (tab[k] == *item);
k ++;
}
assert (k == 5);
rbtree_uint_it_t it, it2;
for (rbtree_uint_it_last(it, tree) ; !rbtree_uint_end_p(it) ; rbtree_uint_previous(it)) {
k--;
rbtree_uint_it_set(it2, it);
assert(rbtree_uint_it_equal_p(it2, it));
assert (tab[k] == *rbtree_uint_cref(it2) );
}
rbtree_uint_it_end(it, tree);
assert (rbtree_uint_end_p(it));
assert(!rbtree_uint_it_equal_p(it2, it));
assert( k == 0);
assert (rbtree_uint_hash(tree) != 0);
rbtree_uint_init(tree3);
rbtree_uint_push(tree3, 5);
rbtree_uint_move(tree3, tree);
rbtree_uint_clear(tree3);
rbtree_uint_init_move(tree, tree2);
rbtree_uint_init_move(tree2, tree);
assert (rbtree_uint_empty_p(tree2));
const unsigned int max = 1001;
for(unsigned int num = 1; num < max; num++) {
rbtree_uint_init(tree);
for(unsigned int i = 0; i < num; i++)
rbtree_uint_push(tree, i);
assert(rbtree_uint_size(tree) == num);
assert(rbtree_uint_empty_p(tree) == false);
if (num > 10) {
rbtree_uint_push(tree, 10);
assert(rbtree_uint_size(tree) == num);
assert(rbtree_uint_empty_p(tree) == false);
}
unsigned int count = 0;
for M_EACH(item, tree, UINT_OPLIST) {
assert (count == *item);
count ++;
}
assert (*rbtree_uint_min(tree) == 0);
assert (*rbtree_uint_max(tree) == num-1);
assert (*rbtree_uint_cmin(tree) == 0);
assert (*rbtree_uint_cmax(tree) == num-1);
assert (count == num);
rbtree_uint_set(tree2, tree);
unsigned int *ptr = rbtree_uint_get(tree2, num/2);
assert (ptr != NULL);
assert (*ptr == num/2);
const unsigned int *cptr = rbtree_uint_cget(tree2, num/2);
assert (cptr != NULL);
assert (*cptr == num/2);
rbtree_uint_clear(tree);
bool b = rbtree_uint_pop_at(NULL, tree2, num+1);
assert (b == false);
for(unsigned int i = 0; i < num; i+=3) {
b = rbtree_uint_pop_at(NULL, tree2, i);
assert(b);
ptr = rbtree_uint_get(tree2, i);
assert (ptr == NULL);
}
for(unsigned int i = 1; i < num; i+=3) {
b = rbtree_uint_pop_at(NULL, tree2, i);
assert(b);
ptr = rbtree_uint_get(tree2, i);
assert (ptr == NULL);
}
}
rbtree_uint_init (tree);
assert(rbtree_uint_empty_p(tree));
rbtree_uint_clean(tree2);
rbtree_uint_push(tree2, 17421);
assert(rbtree_uint_size(tree2) == 1);
rbtree_uint_swap(tree, tree2);
assert(rbtree_uint_empty_p(tree2));
assert(rbtree_uint_size(tree) == 1);
unsigned int *ptr = rbtree_uint_get(tree, 17421);
assert(ptr != NULL && *ptr == 17421);
rbtree_uint_clear(tree);
rbtree_uint_clear(tree2);
}
static void test_uint_permut(void)
{
const unsigned int max = 1001;
unsigned int tab[1001];
for(unsigned int num = 1; num < max; num++) {
rbtree_uint_t tree;
rbtree_uint_init(tree);
for(unsigned int i = 0; i < num; i++)
tab[i] = i;
for(unsigned int i = 0; i < 2 * num; i++) {
int j = rand() % num;
int k = rand() % num;
M_SWAP(unsigned int, tab[j], tab[k]);
}
for(unsigned int i = 0; i < num; i++)
rbtree_uint_push(tree, tab[i]);
unsigned int k = 0;
for M_EACH(item, tree, UINT_OPLIST) {
assert (k == *item);
k++;
}
rbtree_uint_clear(tree);
}
}
static void test_float(void)
{
M_LET(tree, FLOAT_OP) {
for(float f = -17.42; f < 17.42; f+=0.01)
rbtree_float_push (tree, f);
bool p = false;
float g;
for M_EACH(item, tree, FLOAT_OP) {
if (p) {
assert (g < *item);
}
g = *item;
p = true;
}
}
}
static void test_io(void)
{
M_LET(str, STRING_OPLIST)
M_LET(tree1, tree2, UINT_OPLIST) {
// Empty one
FILE *f = fopen ("a-mrbtree.dat", "wt");
if (!f) abort();
rbtree_uint_out_str(f, tree1);
fclose (f);
f = fopen ("a-mrbtree.dat", "rt");
if (!f) abort();
bool b = rbtree_uint_in_str (tree2, f);
assert (b == true);
assert (rbtree_uint_equal_p (tree1, tree2));
fclose(f);
rbtree_uint_get_str(str, tree1, false);
assert(string_equal_str_p(str, "[]"));
const char *sp;
b = rbtree_uint_parse_str(tree2, string_get_cstr(str), &sp);
assert(b);
assert(*sp == 0);
assert(rbtree_uint_equal_p(tree1, tree2));
// Fill in data
for(unsigned int i = 0 ; i < 10; i++)
rbtree_uint_push(tree1, i);
f = fopen ("a-mrbtree.dat", "wt");
if (!f) abort();
rbtree_uint_out_str(f, tree1);
fclose (f);
f = fopen ("a-mrbtree.dat", "rt");
if (!f) abort();
b = rbtree_uint_in_str (tree2, f);
assert (b == true);
assert (rbtree_uint_equal_p (tree1, tree2));
fclose(f);
rbtree_uint_get_str(str, tree1, false);
assert(string_equal_str_p(str, "[0,1,2,3,4,5,6,7,8,9]"));
b = rbtree_uint_parse_str(tree2, string_get_cstr(str), &sp);
assert(b);
assert(*sp == 0);
assert(rbtree_uint_equal_p(tree1, tree2));
}
}
int main(void)
{
test_uint();
test_uint_permut();
test_float();
test_io();
exit(0);
}