Add framework to test containers againts C++ library
This commit is contained in:
1 parent
4409f613e0
commit
fdfff0c5c5
6 files changed
+703
-5
No files matched your search
+9
-5
@@ -21,6 +21,7 @@
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
CC=cc -std=c99
|
||||
CXX=c++ -std=c++11
|
||||
WCFLAGS_GCC=-Wall -W -pedantic -Wshadow -Wpointer-arith -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wswitch-default -Wswitch-enum -Wcast-align -Wpointer-arith -Wbad-function-cast -Wstrict-overflow=5 -Wundef -Wnested-externs -Wcast-qual -Wshadow -Wunreachable-code -Wlogical-op -Wstrict-aliasing=2 -Wredundant-decls -Wold-style-definition -Wunused-function -ftrapv -Wsign-conversion -Wdate-time -Wconversion -Wformat=2 -Winit-self -Wjump-misses-init -Wstack-protector -Wtrampolines -Wwrite-strings -Wformat-security -Wno-float-conversion -O
|
||||
WCFLAGS_CLANG=-Wall -W -pedantic -Wshadow -Wpointer-arith -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wswitch-default -Wswitch-enum -Wcast-align -Wpointer-arith -Wbad-function-cast -Wstrict-overflow=5 -Winline -Wundef -Wnested-externs -Wcast-qual -Wshadow -Wunreachable-code -Wstrict-aliasing=2 -Wredundant-decls -Wold-style-definition -Wunused-function -ftrapv -Wsign-conversion -O
|
||||
WCFLAGS_CPP=-Wall -W -pedantic -Wshadow -Wpointer-arith -Wcast-qual -Wswitch-default -Wswitch-enum -Wcast-align -Wpointer-arith -Wstrict-overflow=5 -Winline -Wundef -Wcast-qual -Wshadow -Wunreachable-code -Wstrict-aliasing=2 -Wredundant-decls -Wunused-function -ftrapv -Wsign-conversion
|
||||
@@ -44,12 +45,15 @@ all:
|
||||
.POSIX:
|
||||
.PHONY: scan-build sanitize check clean *.log coverage synthesis
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .exe .log .depend .gcov .analyzer
|
||||
.SUFFIXES: .c .exe .log .depend .gcov .analyzer .cpp
|
||||
.SECONDARY:
|
||||
|
||||
.c.exe:
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -g $(LDFLAGS) $< -o $@
|
||||
|
||||
.cpp.exe:
|
||||
$(CXX) $(WCFLAGS_CPP) $(XCFLAGS) $(CPPFLAGS) -g $(LDFLAGS) $< -o $@
|
||||
|
||||
.c.depend:
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -MM -MT `echo $< |$(SED) 's/\.c/\.exe/g'` $< > $@
|
||||
|
||||
@@ -82,14 +86,14 @@ depend:
|
||||
# Clean
|
||||
#####################################################################################################
|
||||
|
||||
exe: depend
|
||||
$(MAKE) `ls test-*.c|$(SED) 's/\.c/\.exe/g'` CC="$(CC)" CFLAGS="$(CFLAGS)"
|
||||
@echo All executable generated
|
||||
|
||||
check: depend
|
||||
$(MAKE) `ls test-*.c|$(SED) 's/\.c/\.log/g'` `ls fail-*.c|$(SED) 's/\.c/\.log/g'` CC="$(CC)" CFLAGS="$(CFLAGS)"
|
||||
@echo All tests passed
|
||||
|
||||
check-stl: depend
|
||||
$(MAKE) `ls check-*.cpp|$(SED) 's/\.cpp/\.log/g'` CXX="$(CXX)" XCFLAGS="-O2 -fsanitize=address,undefined,leak -Wno-sign-conversion -Wno-inline"
|
||||
@echo All comparison against C++ STL passed
|
||||
|
||||
clean:
|
||||
$(RM) *.exe *.s *~ *.o *.log a*.dat
|
||||
$(RM) *.gcda *.gcno *.gcov all.info test.tar *.synt clang_output_* *.c.c *.end.c *.first.c *.middle.c *.analyzer
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 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 <vector>
|
||||
#include "m-array.h"
|
||||
|
||||
ARRAY_DEF(array_int, int)
|
||||
|
||||
// Transform an integer 'i' into a M*LIB base item 'a'
|
||||
#define TYPE_SET_INT(a, i) (a) = (i)
|
||||
|
||||
// Container OPLIST
|
||||
#define CONT_OPL ARRAY_OPLIST(array_int, M_OPL_int())
|
||||
|
||||
// C++ Base class of the item in the container
|
||||
#define BASE_CLASS int
|
||||
|
||||
// Transform an integer 'i' into a C++ base item 'a'
|
||||
#define CLASS_SET_INT(a, i) (a) = (i)
|
||||
|
||||
// C++ Container class
|
||||
#define CONT_CLASS std::vector<int>
|
||||
|
||||
// Compare the M*LIB container a to the C++ container b
|
||||
#define CMP_CONT(a, b) cmp_cont(a, b)
|
||||
|
||||
// Compate the M*LIB base object to the C++ base object
|
||||
#define CMP_BASE(a, b) assert( (a) == (b) )
|
||||
|
||||
void cmp_cont(array_int_t a, std::vector<int> b)
|
||||
{
|
||||
size_t s = array_int_size(a);
|
||||
assert (s == b.size());
|
||||
for(size_t i = 0; i < s; i++) {
|
||||
int *b0 = array_int_get(a, i);
|
||||
int &b1 = b.at(i);
|
||||
CMP_BASE(*b0, b1);
|
||||
}
|
||||
}
|
||||
|
||||
#define DEFAULT_NUMBER 1000000
|
||||
#include "check-generic.hpp"
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 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 <deque>
|
||||
#include "m-deque.h"
|
||||
|
||||
DEQUE_DEF(deque_float, float)
|
||||
|
||||
// Transform an integer 'i' into a M*LIB base item 'a'
|
||||
#define TYPE_SET_INT(a, i) (a) = (i)
|
||||
|
||||
// Container OPLIST
|
||||
#define CONT_OPL DEQUE_OPLIST(deque_float, M_OPL_float())
|
||||
|
||||
// C++ Base class of the item in the container
|
||||
#define BASE_CLASS float
|
||||
|
||||
// Transform an integer 'i' into a C++ base item 'a'
|
||||
#define CLASS_SET_INT(a, i) (a) = (i)
|
||||
|
||||
// C++ Container class
|
||||
#define CONT_CLASS std::deque<float>
|
||||
|
||||
// Compare the M*LIB container a to the C++ container b
|
||||
#define CMP_CONT(a, b) cmp_cont(a, b)
|
||||
|
||||
// Compate the M*LIB base object to the C++ base object
|
||||
#define CMP_BASE(a, b) assert( (a) == (b) )
|
||||
|
||||
void cmp_cont(deque_float_t a, std::deque<float> b)
|
||||
{
|
||||
deque_float_it_t ita;
|
||||
deque_float_it(ita, a);
|
||||
auto itb = b.begin();
|
||||
while (itb != b.end()) {
|
||||
assert(!deque_float_end_p(ita));
|
||||
const float *b0 = deque_float_cref(ita);
|
||||
float &b1 = *itb;
|
||||
CMP_BASE(*b0, b1);
|
||||
itb++;
|
||||
deque_float_next(ita);
|
||||
}
|
||||
assert(deque_float_end_p(ita));
|
||||
}
|
||||
|
||||
#define DEFAULT_NUMBER 1000000
|
||||
#define HAVE_PUSH_FRONT
|
||||
#define HAVE_POP_FRONT
|
||||
#include "check-generic.hpp"
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 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 <list>
|
||||
#include "m-list.h"
|
||||
|
||||
LIST_DUAL_PUSH_DEF(list_int, int)
|
||||
|
||||
// Transform an integer 'i' into a M*LIB base item 'a'
|
||||
#define TYPE_SET_INT(a, i) (a) = (i)
|
||||
|
||||
// Container OPLIST
|
||||
#define CONT_OPL LIST_OPLIST(list_int, M_OPL_int())
|
||||
|
||||
// C++ Base class of the item in the container
|
||||
#define BASE_CLASS int
|
||||
|
||||
// Transform an integer 'i' into a C++ base item 'a'
|
||||
#define CLASS_SET_INT(a, i) (a) = (i)
|
||||
|
||||
// C++ Container class
|
||||
#define CONT_CLASS std::list<int>
|
||||
|
||||
// Compare the M*LIB container a to the C++ container b
|
||||
#define CMP_CONT(a, b) cmp_cont(a, b)
|
||||
|
||||
// Compate the M*LIB base object to the C++ base object
|
||||
#define CMP_BASE(a, b) assert( (a) == (b) )
|
||||
|
||||
void cmp_cont(const list_int_t a, const std::list<int> &b)
|
||||
{
|
||||
list_int_it_t ita;
|
||||
list_int_it(ita, a);
|
||||
auto itb = b.rbegin();
|
||||
while (itb != b.rend()) {
|
||||
assert(!list_int_end_p(ita));
|
||||
const int *b0 = list_int_cref(ita);
|
||||
const int &b1 = *itb;
|
||||
//printf("%d VS %d\n", *b0, b1);
|
||||
CMP_BASE(*b0, b1);
|
||||
itb++;
|
||||
list_int_next(ita);
|
||||
}
|
||||
assert(list_int_end_p(ita));
|
||||
}
|
||||
|
||||
#define DEFAULT_NUMBER 100000
|
||||
|
||||
#define HAVE_PUSH_FRONT
|
||||
#define HAVE_REVERSE_IT
|
||||
|
||||
#include "check-generic.hpp"
|
||||
@@ -0,0 +1,421 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 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 <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* This test will perform random generic operations on the
|
||||
M*LIB container and compares it to the same operation on the
|
||||
C++ equivalent container.
|
||||
If there are some differences, it reports an error.
|
||||
It is therefore quite generic and based on the properties of the container
|
||||
*/
|
||||
|
||||
/* Get the types from the container oplist if needed */
|
||||
#ifndef CONT_TYPE
|
||||
# define CONT_TYPE_(CONT_OPL) M_GET_TYPE CONT_OPL
|
||||
# define CONT_TYPE CONT_TYPE_(CONT_OPL)
|
||||
#endif
|
||||
#ifndef BASE_TYPE
|
||||
# define BASE_TYPE_(CONT_OPL) M_GET_SUBTYPE CONT_OPL
|
||||
# define BASE_TYPE BASE_TYPE_(CONT_OPL)
|
||||
#endif
|
||||
|
||||
#define CONT_NAME_(CONT_OPL) M_GET_NAME CONT_OPL
|
||||
#define CONT_NAME CONT_NAME_(CONT_OPL)
|
||||
|
||||
#define MAX_TEST 25
|
||||
|
||||
#ifdef HAVE_REVERSE_IT
|
||||
// Scan the C++ sequence in reverse
|
||||
# define begin rbegin
|
||||
# define end rend
|
||||
# define IT(x) std::prev(x.base(), 1)
|
||||
#else
|
||||
# define IT(x) x
|
||||
#endif
|
||||
|
||||
volatile int test_case;
|
||||
|
||||
void test(int select_test, int index,
|
||||
BASE_TYPE &b0, BASE_CLASS &b1, CONT_TYPE &c0, CONT_CLASS &c1)
|
||||
{
|
||||
bool p0 = false, p1 = false;
|
||||
size_t s0 = 0, s1 = 0;
|
||||
CONT_TYPE tmp;
|
||||
#if M_TEST_METHOD_P(IT_TYPE, CONT_OPL)
|
||||
M_ID(M_GET_IT_TYPE CONT_OPL) it0;
|
||||
auto it1 = c1.begin();
|
||||
#endif
|
||||
|
||||
// Save in a volatile variable the last test for debug purpose
|
||||
test_case = select_test % MAX_TEST;
|
||||
#ifdef DEBUG
|
||||
printf("Case=%d\n", test_case);
|
||||
#endif
|
||||
switch (test_case) {
|
||||
#if M_TEST_METHOD_P(PUSH, CONT_OPL)
|
||||
case 0:
|
||||
TYPE_SET_INT(b0, index);
|
||||
CLASS_SET_INT(b1, index);
|
||||
M_CALL_PUSH(CONT_OPL, c0, b0);
|
||||
c1.push_back(b1);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
index = index % 1000;
|
||||
for(int i = 0; i < index; i++) {
|
||||
TYPE_SET_INT(b0, i);
|
||||
CLASS_SET_INT(b1, i);
|
||||
M_CALL_PUSH(CONT_OPL, c0, b0);
|
||||
c1.push_back(b1);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if M_TEST_METHOD_P(POP, CONT_OPL)
|
||||
case 2:
|
||||
if (!c1.empty()) {
|
||||
M_CALL_POP(CONT_OPL, &b0, c0);
|
||||
b1 = c1.back();
|
||||
c1.pop_back();
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if M_TEST_METHOD_P(EMPTY_P, CONT_OPL)
|
||||
case 3:
|
||||
p0 = M_CALL_EMPTY_P(CONT_OPL, c0);
|
||||
p1 = c1.empty();
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if M_TEST_METHOD_P(SIZE, CONT_OPL)
|
||||
case 4:
|
||||
s0 = M_CALL_SIZE(CONT_OPL, c0);
|
||||
s1 = c1.size();
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if M_TEST_METHOD_P(CLEAN, CONT_OPL)
|
||||
case 5:
|
||||
M_CALL_CLEAN(CONT_OPL, c0);
|
||||
c1.clear();
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if M_TEST_METHOD_P(GET_KEY, CONT_OPL)
|
||||
case 6:
|
||||
if (!c1.empty()) {
|
||||
// To rework for dict
|
||||
index = index % c1.size();
|
||||
M_CALL_SET(M_GET_OPLIST CONT_OPL, b0, *M_CALL_GET_KEY(CONT_OPL, c0, index));
|
||||
b1 = c1[index];
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if M_TEST_METHOD_P(SET_KEY, CONT_OPL)
|
||||
case 7:
|
||||
if (!c1.empty()) {
|
||||
TYPE_SET_INT(b0, index);
|
||||
CLASS_SET_INT(b1, index);
|
||||
index = index % c1.size();
|
||||
M_CALL_SET_KEY(CONT_OPL, c0, index, b0);
|
||||
c1[index] = b1;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if M_TEST_METHOD_P(ERASE_KEY, CONT_OPL)
|
||||
case 8:
|
||||
if (!c1.empty()) {
|
||||
index = index % c1.size();
|
||||
p0 = M_CALL_ERASE_KEY(CONT_OPL, c0, index);
|
||||
c1.erase(c1.begin() + index);
|
||||
p1 = true;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if M_TEST_METHOD_P(SET, CONT_OPL) && M_TEST_METHOD_P(INIT_SET, CONT_OPL)
|
||||
case 9:
|
||||
M_CALL_INIT_SET(CONT_OPL, tmp, c0);
|
||||
#if M_TEST_METHOD_P(EQUAL_P, CONT_OPL)
|
||||
assert( M_CALL_EQUAL_P(CONT_OPL, tmp, c0) );
|
||||
#endif
|
||||
M_CALL_SET(CONT_OPL, c0, tmp);
|
||||
M_CALL_CLEAR(CONT_OPL, tmp);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if M_TEST_METHOD_P(INIT_MOVE, CONT_OPL)
|
||||
case 10:
|
||||
M_CALL_INIT_MOVE(CONT_OPL, tmp, c0);
|
||||
M_CALL_INIT_MOVE(CONT_OPL, c0, tmp);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if M_TEST_METHOD_P(MOVE, CONT_OPL) && M_TEST_METHOD_P(INIT_MOVE, CONT_OPL)
|
||||
case 11:
|
||||
M_CALL_INIT_SET(CONT_OPL, tmp, c0);
|
||||
M_CALL_MOVE(CONT_OPL, tmp, c0);
|
||||
M_CALL_INIT_MOVE(CONT_OPL, c0, tmp);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if M_TEST_METHOD_P(SWAP, CONT_OPL) && M_TEST_METHOD_P(GET_SIZE, CONT_OPL)
|
||||
case 12:
|
||||
s0 = M_CALL_GET_SIZE(CONT_OPL, c0);
|
||||
M_CALL_INIT(CONT_OPL, tmp);
|
||||
M_CALL_SWAP(CONT_OPL, tmp, c0);
|
||||
s1 = M_CALL_GET_SIZE(CONT_OPL, tmp);
|
||||
M_CALL_SWAP(CONT_OPL, tmp, c0);
|
||||
M_CALL_CLEAR(CONT_OPL, tmp);
|
||||
break;
|
||||
case 13:
|
||||
M_CALL_INIT_SET(CONT_OPL, tmp, c0);
|
||||
M_CALL_SWAP(CONT_OPL, tmp, c0);
|
||||
M_CALL_CLEAR(CONT_OPL, tmp);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if M_TEST_METHOD_P(GET_SET_KEY, CONT_OPL)
|
||||
case 14:
|
||||
// To rework for dict
|
||||
index = (1 + (c1.size() < 1000000)) * (index % ( c1.size() + 1) );
|
||||
M_CALL_SET(M_GET_OPLIST CONT_OPL, b0, *M_CALL_GET_SET_KEY(CONT_OPL, c0, index));
|
||||
if ((size_t) index >= c1.size() ) {
|
||||
c1.resize(index+1);
|
||||
}
|
||||
b1 = c1[index];
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if M_TEST_METHOD_P(IT_CREF, CONT_OPL)
|
||||
case 15:
|
||||
M_CALL_IT_FIRST(CONT_OPL, it0, c0);
|
||||
it1 = c1.begin();
|
||||
while (it1 != c1.end()) {
|
||||
assert( !M_CALL_IT_END_P(CONT_OPL, it0));
|
||||
M_CALL_SET(M_GET_OPLIST CONT_OPL, b0, *M_CALL_IT_CREF(CONT_OPL, it0));
|
||||
b1 = *it1;
|
||||
CMP_BASE(b0, b1);
|
||||
M_CALL_IT_NEXT(CONT_OPL, it0);
|
||||
it1++;
|
||||
}
|
||||
assert(M_CALL_IT_END_P(CONT_OPL, it0));
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if M_TEST_METHOD_P(IT_REF, CONT_OPL)
|
||||
case 16:
|
||||
M_CALL_IT_FIRST(CONT_OPL, it0, c0);
|
||||
it1 = c1.begin();
|
||||
while (it1 != c1.end()) {
|
||||
assert( !M_CALL_IT_END_P(CONT_OPL, it0));
|
||||
TYPE_SET_INT(b0, index);
|
||||
CLASS_SET_INT(b1, index);
|
||||
M_CALL_SET(M_GET_OPLIST CONT_OPL, *M_CALL_IT_REF(CONT_OPL, it0), b0);
|
||||
*it1 = b1;
|
||||
M_CALL_IT_NEXT(CONT_OPL, it0);
|
||||
it1++;
|
||||
index = 1457857U * index + 458741U;
|
||||
}
|
||||
assert(M_CALL_IT_END_P(CONT_OPL, it0));
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if M_TEST_METHOD_P(IT_LAST, CONT_OPL)
|
||||
case 17:
|
||||
{
|
||||
M_CALL_IT_LAST(CONT_OPL, it0, c0);
|
||||
auto it1b = c1.rbegin();
|
||||
while (it1b != c1.rend()) {
|
||||
assert( !M_CALL_IT_END_P(CONT_OPL, it0));
|
||||
M_CALL_SET(M_GET_OPLIST CONT_OPL, b0, *M_CALL_IT_CREF(CONT_OPL, it0));
|
||||
b1 = *it1b;
|
||||
CMP_BASE(b0, b1);
|
||||
M_CALL_IT_PREVIOUS(CONT_OPL, it0);
|
||||
it1b++;
|
||||
}
|
||||
assert(M_CALL_IT_END_P(CONT_OPL, it0));
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if M_TEST_METHOD_P(IT_INSERT, CONT_OPL)
|
||||
case 18:
|
||||
M_CALL_IT_FIRST(CONT_OPL, it0, c0);
|
||||
it1 = c1.begin();
|
||||
TYPE_SET_INT(b0, index);
|
||||
CLASS_SET_INT(b1, index);
|
||||
#ifdef HAVE_INSERT_AFTER
|
||||
while (it1 != c1.end() ) {
|
||||
if (rand() > index)
|
||||
break;
|
||||
M_CALL_IT_NEXT(CONT_OPL, it0);
|
||||
it1++;
|
||||
}
|
||||
if (it1 != c1.end() ) {
|
||||
M_CALL_IT_INSERT(CONT_OPL, c0, it0, b0);
|
||||
c1.insert_after(it1, b1);
|
||||
}
|
||||
#else
|
||||
if (!c1.empty() ){
|
||||
index = index % c1.size();
|
||||
if (index == 0) {
|
||||
M_CALL_IT_END(CONT_OPL, it0, c0);
|
||||
} else {
|
||||
for(int i = 0; i < index; i++) {
|
||||
assert( it1 != c1.end());
|
||||
assert( !M_CALL_IT_END_P(CONT_OPL, it0));
|
||||
M_CALL_IT_NEXT(CONT_OPL, it0);
|
||||
it1++;
|
||||
}
|
||||
it1++;
|
||||
}
|
||||
}
|
||||
M_CALL_IT_INSERT(CONT_OPL, c0, it0, b0);
|
||||
#ifdef HAVE_REVERSE_IT
|
||||
// in cases of reverse iterator, fix iterator.
|
||||
it1 = std::prev(it1, 1);
|
||||
#endif
|
||||
c1.insert(IT(it1), b1);
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if M_TEST_METHOD_P(IT_REMOVE, CONT_OPL)
|
||||
case 19:
|
||||
M_CALL_IT_FIRST(CONT_OPL, it0, c0);
|
||||
it1 = c1.begin();
|
||||
#ifdef HAVE_ERASE_AFTER
|
||||
while (it1 != c1.end() ) {
|
||||
M_CALL_IT_NEXT(CONT_OPL, it0);
|
||||
if (rand() > index)
|
||||
break;
|
||||
it1++;
|
||||
}
|
||||
if (it1 != c1.end() && !M_CALL_IT_END_P(CONT_OPL, it0) ) {
|
||||
M_CALL_IT_REMOVE(CONT_OPL, c0, it0);
|
||||
c1.erase_after(it1);
|
||||
}
|
||||
#else
|
||||
if (!c1.empty() ){
|
||||
index = index % c1.size();
|
||||
for(int i = 0; i < index; i++) {
|
||||
assert( it1 != c1.end());
|
||||
assert( !M_CALL_IT_END_P(CONT_OPL, it0));
|
||||
M_CALL_IT_NEXT(CONT_OPL, it0);
|
||||
it1++;
|
||||
}
|
||||
M_CALL_IT_REMOVE(CONT_OPL, c0, it0);
|
||||
c1.erase(IT(it1));
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if M_TEST_METHOD_P(REVERSE, CONT_OPL)
|
||||
case 20:
|
||||
M_CALL_REVERSE(CONT_OPL, c0);
|
||||
c1.reverse();
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if M_TEST_METHOD_P(SPLICE_BACK, CONT_OPL)
|
||||
case 21:
|
||||
M_CALL_REVERSE(CONT_OPL, c0);
|
||||
c1.reverse();
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PUSH_FRONT
|
||||
case 22:
|
||||
TYPE_SET_INT(b0, index);
|
||||
CLASS_SET_INT(b1, index);
|
||||
M_C(CONT_NAME, _push_front)(c0, b0);
|
||||
c1.push_front(b1);
|
||||
break;
|
||||
|
||||
case 23:
|
||||
index = index % 1000;
|
||||
for(int i = 0; i < index; i++) {
|
||||
TYPE_SET_INT(b0, i);
|
||||
CLASS_SET_INT(b1, i);
|
||||
M_C(CONT_NAME, _push_front)(c0, b0);
|
||||
c1.push_front(b1);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_POP_FRONT
|
||||
case 24:
|
||||
if (!c1.empty()) {
|
||||
M_C(CONT_NAME, _pop_front)(&b0, c0);
|
||||
b1 = c1.front();
|
||||
c1.pop_front();
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
// SPLICE_BACK
|
||||
// SPLICE_AT
|
||||
// Needs SPLICE ?
|
||||
|
||||
default:
|
||||
// Nothing to do
|
||||
break;
|
||||
}
|
||||
CMP_BASE(b0, b1);
|
||||
CMP_CONT(c0, c1);
|
||||
assert(p0 == p1);
|
||||
assert(s0 == s1);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
int loop = argc >= 2 ? atoi(argv[1]) : DEFAULT_NUMBER;
|
||||
|
||||
BASE_TYPE b0;
|
||||
BASE_CLASS b1;
|
||||
CONT_TYPE c0;
|
||||
CONT_CLASS c1;
|
||||
|
||||
M_CALL_INIT(CONT_OPL, c0);
|
||||
M_CALL_INIT(M_GET_OPLIST CONT_OPL, b0);
|
||||
TYPE_SET_INT(b0, 0);
|
||||
CLASS_SET_INT(b1, 0);
|
||||
|
||||
for(int i = 0; i < loop; i++) {
|
||||
int t = rand();
|
||||
int s = rand();
|
||||
test(t, s, b0, b1, c0, c1);
|
||||
}
|
||||
|
||||
M_CALL_CLEAR(M_GET_OPLIST CONT_OPL, b0);
|
||||
M_CALL_CLEAR(CONT_OPL, c0);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 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 <forward_list>
|
||||
#include "m-list.h"
|
||||
|
||||
LIST_DEF(list_int, int)
|
||||
|
||||
// Transform an integer 'i' into a M*LIB base item 'a'
|
||||
#define TYPE_SET_INT(a, i) (a) = (i)
|
||||
|
||||
// Container OPLIST
|
||||
#define CONT_OPL LIST_OPLIST(list_int, M_OPL_int())
|
||||
|
||||
// C++ Base class of the item in the container
|
||||
#define BASE_CLASS int
|
||||
|
||||
// Transform an integer 'i' into a C++ base item 'a'
|
||||
#define CLASS_SET_INT(a, i) (a) = (i)
|
||||
|
||||
// C++ Container class
|
||||
#define CONT_CLASS std::forward_list<int>
|
||||
|
||||
// Compare the M*LIB container a to the C++ container b
|
||||
#define CMP_CONT(a, b) cmp_cont(a, b)
|
||||
|
||||
// Compate the M*LIB base object to the C++ base object
|
||||
#define CMP_BASE(a, b) assert( (a) == (b) )
|
||||
|
||||
void cmp_cont(list_int_t a, std::forward_list<int> b)
|
||||
{
|
||||
list_int_it_t ita;
|
||||
list_int_it(ita, a);
|
||||
auto itb = b.begin();
|
||||
while (itb != b.end()) {
|
||||
assert(!list_int_end_p(ita));
|
||||
const int *b0 = list_int_cref(ita);
|
||||
int &b1 = *itb;
|
||||
CMP_BASE(*b0, b1);
|
||||
itb++;
|
||||
list_int_next(ita);
|
||||
}
|
||||
assert(list_int_end_p(ita));
|
||||
}
|
||||
|
||||
#define HAVE_INSERT_AFTER
|
||||
#define HAVE_ERASE_AFTER
|
||||
#define DEFAULT_NUMBER 100000
|
||||
|
||||
// C++ forward_list pushs in front instead of in back
|
||||
#define push_back push_front
|
||||
#define pop_back pop_front
|
||||
#define back front
|
||||
#include "check-generic.hpp"
|
||||
Reference in new issue
Block a user