Files
mlib/tests/test-mdeque.c
T

238 lines
6.3 KiB
C

/*
* Copyright (c) 2017-2018, 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 "mympz.h"
#include "m-string.h"
#include "m-deque.h"
#include "coverage.h"
START_COVERAGE
DEQUE_DEF(deque, int)
END_COVERAGE
DEQUE_DEF(deque_mpz, my_mpz_t, MY_MPZ_OPLIST)
#define OPL DEQUE_OPLIST(deque)
static void test_ti1(int n)
{
deque_t d;
deque_init(d);
for(int i =0; i < n ;i++) {
deque_push_back(d, i);
assert(*deque_back(d) == i);
deque_push_front(d, i);
assert(*deque_front(d) == i);
}
assert (!deque_empty_p(d));
assert (deque_size(d) == (size_t)2*n);
int s = 0;
for(int i =0; i < 2*n ;i++) {
int z;
if ((i % 3) == 0) {
deque_pop_front(&z, d);
assert (z > *deque_front(d) );
} else {
deque_pop_back(&z, d);
}
s += z;
}
assert (s == n*(n-1) );
assert (deque_empty_p(d));
assert (deque_size(d) == 0);
deque_clear(d);
}
static void test1(void)
{
deque_t d;
deque_init(d);
assert (deque_empty_p(d));
assert (deque_size(d) == 0);
deque_push_back_new(d);
assert (!deque_empty_p(d));
assert (deque_size(d) == 1);
assert (*deque_back(d) == 0);
*deque_back(d) = -1;
deque_push_front_new(d);
assert (!deque_empty_p(d));
assert (deque_size(d) == 2);
assert (*deque_front(d) == 0);
*deque_front(d) = 1;
assert (*deque_back(d) == -1);
assert (*deque_cget(d, 0) == 1);
assert (*deque_cget(d, 1) == -1);
for(int i = -2; i > -100; i--) {
deque_push_back(d, i);
assert (*deque_back(d) == i);
}
for(int i = 2; i < 100; i++) {
deque_push_front(d, i);
assert (*deque_front(d) == i);
}
assert (deque_size(d) == 99*2);
for(int i = 0; i < 99*2; i++)
assert (*deque_get(d, i) == (i < 99) ? i - 99 : i - 98);
for(int i = 0; i < 50; i++) {
deque_pop_back(NULL, d);
assert (*deque_back(d) == i - 98);
deque_pop_front(NULL, d);
assert (*deque_front(d) == 98 - i);
}
deque_clear(d);
}
static void test_it(void)
{
M_LET(d, OPL) {
for(size_t i = 0; i < 1997; i ++) {
deque_push_back(d, 1997+i);
deque_push_front(d, 1996-i);
deque_it_t it;
deque_it_last (it, d);
assert (deque_last_p(it));
assert (*deque_cref (it) == (int)(1997+i));
deque_it(it, d);
assert (*deque_cref (it) == (int)(1996-i));
}
int s = 0;
for M_EACH(it, d, OPL) {
assert (*it == s++);
}
deque_it_t it;
deque_it(it, d);
assert (!deque_end_p(it));
assert (!deque_last_p(it));
assert (*deque_cref(it) == 0);
deque_it_last(it, d);
assert (!deque_end_p(it));
assert (deque_last_p(it));
assert (*deque_ref(it) == 1997+1996);
deque_next(it);
assert (deque_last_p(it));
assert (deque_end_p(it));
deque_it_last(it, d);
while (!deque_end_p(it)) {
deque_previous(it);
assert (deque_end_p(it) || !deque_last_p(it));
}
deque_previous(it);
assert (deque_end_p(it));
deque_it_end(it, d);
assert (deque_end_p(it));
assert (deque_last_p(it));
deque_it_t it2;
deque_it_set(it2, it);
assert (deque_end_p(it2));
assert (deque_it_equal_p(it, it2));
for(size_t i = 1996; i < 1997; i --) {
int z;
deque_pop_back(&z, d);
assert (z == 1997+(int)i);
deque_it_last (it, d);
assert (deque_last_p(it));
assert (deque_end_p(it) || *deque_cref (it) == (int)(1996+i));
}
}
M_LET(d, OPL) {
deque_it_t it;
deque_it_last (it, d);
assert(deque_last_p(it));
assert(deque_end_p(it));
}
}
static void test_set(void)
{
M_LET(e, d, OPL) {
assert (deque_equal_p(d, e));
for(size_t i = 0; i < 1997; i ++)
deque_push_back(d, i);
assert (!deque_equal_p(d, e));
deque_set(e, d);
deque_set (e, e);
assert (deque_size(e) == deque_size (d));
deque_it_t it1, it2;
for(deque_it(it1, e), deque_it (it2, d) ;
!deque_end_p (it1) && !deque_end_p (it2) ;
deque_next(it1) , deque_next (it2)) {
assert (*deque_ref(it1) == *deque_ref(it2));
}
assert (deque_end_p (it1));
assert (deque_end_p (it2));
assert (deque_equal_p(d, e));
assert (deque_hash(d) != 0);
deque_clean (e);
assert (deque_size (d) == 1997);
assert (deque_size (e) == 0);
deque_swap(d, e);
assert (deque_size (d) == 0);
assert (deque_size (e) == 1997);
deque_set_at (e, 0, 2000);
assert (*deque_front(e) == 2000);
deque_set_at (e, deque_size(e)-1, 3000);
assert (*deque_back(e) == 3000);
deque_clear(d);
deque_init_move (d, e);
deque_init (e);
deque_move (e, d);
deque_init (d);
assert (*deque_back(e) == 3000);
}
}
// This test showed a very bad behavior in the memory allocator
// deque will continously allocate a new space whereas at most only
// one item is in the container!
// This is still quite slow.
static void test_advance(void)
{
deque_t d;
int j;
deque_init(d);
for(int i = 0; i < 100000000; i ++) {
deque_push_back(d, i);
deque_pop_front(&j, d);
assert (i == j);
}
deque_clear(d);
}
int main(void)
{
test1();
test_ti1(10);
test_ti1(100);
test_ti1(1000);
test_ti1(10000);
test_it();
test_set();
test_advance();
exit(0);
}