/* * Copyright (c) 2017-2025, 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 "m-list.h" #include "m-i-list.h" #include "m-array.h" #include "m-string.h" #include "m-deque.h" #include "m-dict.h" #include "m-tuple.h" #include "m-algo.h" #include "test-obj.h" typedef struct over_s { unsigned long data; ILIST_INTERFACE(ilist_over, over_s); } over_t; // TODO: Test Intrusive List // HASHMAP, RBTREE, B+TREE: Is this useful? ARRAY_DEF(array_int, int) #define M_OPL_array_int_t() ARRAY_OPLIST(array_int) LIST_DEF(list_int, int) ILIST_DEF(ilist_over, over_t, M_POD_OPLIST) LIST_DEF(list_string, string_t, STRING_OPLIST) DEQUE_DEF(deque_obj, testobj_t, TESTOBJ_CMP_OPLIST) #define M_OPL_deque_obj_t() DEQUE_OPLIST(deque_obj, TESTOBJ_CMP_OPLIST) DICT_DEF2(dict_obj, string_t, STRING_OPLIST, testobj_t, TESTOBJ_OPLIST) LIST_DUAL_PUSH_DEF(dlist_int, int) DICT_DEF2(dict_int, string_t, int) #define M_OPL_dict_int_t() DICT_OPLIST(dict_int, STRING_OPLIST, M_BASIC_OPLIST) ARRAY_DEF(array_uint, unsigned int) #define M_OPL_array_uint_t() ARRAY_OPLIST(array_uint) TUPLE_DEF2(person, (age, int), (name, string_t) ) #define M_OPL_person_t() TUPLE_OPLIST(person, M_BASIC_OPLIST, STRING_OPLIST) ARRAY_DEF(array_person, person_t) #define M_OPL_array_person_t() ARRAY_OPLIST(array_person, M_OPL_person_t() ) #include "coverage.h" START_COVERAGE ALGO_DEF(algo_array, array_int_t) ALGO_DEF(algo_list, LIST_OPLIST(list_int)) ALGO_DEF(algo_over, ILIST_OPLIST(ilist_over, M_POD_OPLIST)) ALGO_DEF(algo_string, LIST_OPLIST(list_string, STRING_OPLIST)) ALGO_DEF(algo_deque, deque_obj_t) ALGO_DEF(algo_dict, DICT_OPLIST(dict_obj, STRING_OPLIST, TESTOBJ_OPLIST)) END_COVERAGE ALGO_DEF(algo_dlist, LIST_OPLIST(list_int)) // Needs to be included ***AFTER*** so that the algorithms can be generated without Function Object before. #include "m-funcobj.h" ALGO_DEF(algo_array_fo, array_int_t) ALGO_DEF(algo_list_fo, LIST_OPLIST(list_int)) /* Helper functions */ int g_min, g_max, g_count; static void g_f(int n) { assert (g_min <= n && n <= g_max); g_count++; } static void func_map(int *d, int n) { assert (g_min <= n && n <= g_max); g_count++; *d = n * n; } static void func_reduce(int *d, int n) { *d += n; } static bool func_test_42(int d) { return d == 42; } static bool func_test_101(int d) { return d == 101; } static bool func_test_pos(int d) { return d >= 0; } static bool func_test_both_even_or_odd(int a, int b) { return (a&1) == (b&1); } #define start_with(pattern, item) \ string_start_with_str_p((item).key, (pattern)) #define get_value(out, item) ((out) = (item).value) /* Tests starts */ static void test_list(void) { list_int_t l; list_int_init(l); for(int i = 0; i < 100; i++) list_int_push_back (l, i); assert( algo_list_contain_p(l, 62) == true); assert( algo_list_contain_p(l, -1) == false); assert( algo_list_count(l, 1) == 1); list_int_push_back (l, 17); assert( algo_list_count(l, 17) == 2); assert( algo_list_count(l, -1) == 0); assert (algo_list_all_of_p(l, func_test_42) == false); assert (algo_list_any_of_p(l, func_test_42) == true); assert (algo_list_none_of_p(l, func_test_42) == false); assert (algo_list_all_of_p(l, func_test_101) == false); assert (algo_list_any_of_p(l, func_test_101) == false); assert (algo_list_none_of_p(l, func_test_101) == true); assert (algo_list_all_of_p(l, func_test_pos) == true); assert (algo_list_any_of_p(l, func_test_pos) == true); assert (algo_list_none_of_p(l, func_test_pos) == false); #define f(x) assert((x) >= 0 && (x) < 100); ALGO_FOR_EACH(l, LIST_OPLIST(list_int), f); #define g(y, x) assert((x) >= 0 && (x) < y); ALGO_FOR_EACH(l, LIST_OPLIST(list_int), g, 100); assert( algo_list_count_if(l, func_test_42) == 1); assert( algo_list_count_if(l, func_test_101) == 0); M_LET(tmp, LIST_OPLIST(list_int)) { g_min = 0; g_max = 99; g_count = 0; algo_list_transform(tmp, l, func_map); assert(g_count == 101); assert(list_int_size(tmp) == 101); for(int i = 0; i < 100; i++) { assert(*list_int_get(tmp, (size_t) i) == i * i); } assert(*list_int_get(tmp, 100) == 17 * 17); } int *p = algo_list_min(l); assert(p != NULL && *p == 0); p = algo_list_max(l); assert(p != NULL && *p == 99); int *p2; algo_list_minmax(&p, &p2, l); assert(p != NULL && *p == 0); assert(p2 != NULL && *p2 == 99); list_int_push_back (l, 3); list_int_it_t it1, it2; algo_list_find (it1, l, 3); assert (!list_int_end_p (it1)); algo_list_find_last (it2, l, 3); assert (!list_int_end_p (it2)); assert (!list_int_it_equal_p(it1, it2)); algo_list_find_if(it1, l, func_test_101); assert (list_int_end_p (it1)); algo_list_find_if(it1, l, func_test_42); assert (!list_int_end_p (it1)); assert (*list_int_cref(it1) == 42); algo_list_mismatch(it1, it2, l, l); assert (list_int_end_p (it1)); assert (list_int_end_p (it2)); for(int i = -100; i < 100; i+=2) list_int_push_back (l, i); assert (!algo_list_sort_p(l)); algo_list_sort(l); assert (algo_list_sort_p(l)); list_int_clear(l); list_int_init(l); for(int i = 1; i <= 5; i++) list_int_push_back(l, i); assert (list_int_size(l) == 5); algo_list_remove_val(l, 3); assert (list_int_size(l) == 4); algo_list_find (it1, l, 3); assert (list_int_end_p (it1)); algo_list_remove_val(l, 3); assert (list_int_size(l) == 4); algo_list_remove_if(l, func_test_42); assert (list_int_size(l) == 4); list_int_push_back(l, 42); list_int_push_back(l, 43); list_int_push_back(l, 42); algo_list_remove_if(l, func_test_42); assert (list_int_size(l) == 5); algo_list_find (it1, l, 42); assert (list_int_end_p (it1)); list_int_clear(l); M_LET( (l1, 1, 3, 5), (l2, 1, 2, 4), (l3, 1, 2, 3, 4, 5), LIST_OPLIST(list_int, M_BASIC_OPLIST)) { algo_list_sort_union(l1, l2); assert(list_int_equal_p (l1, l3)); } M_LET( (l1, 1, 30, 31), (l2, 2, 4, 31, 32), (l3, 1, 2, 4, 30, 31, 32), LIST_OPLIST(list_int, M_BASIC_OPLIST)) { algo_list_sort_union(l1, l2); assert(list_int_equal_p (l1, l3)); } M_LET( (l1, 4, 28, 29, 30, 34), (l2, 1, 3, 31, 32, 33), (l3, 1, 3, 4, 28, 29, 30, 31, 32, 33, 34), LIST_OPLIST(list_int, M_BASIC_OPLIST)) { algo_list_sort_union(l1, l2); assert(list_int_equal_p (l1, l3)); } M_LET( (l1, 1, 4, 28, 29, 31, 34), (l2, 1, 3, 31, 32, 33), (l3, 1, 31), LIST_OPLIST(list_int, M_BASIC_OPLIST)) { algo_list_sort_intersect(l1, l2); assert(list_int_equal_p (l1, l3)); } M_LET( (l1, 4, 28, 29, 31, 34), (l2, 1, 3, 31, 32, 33), (l3, (31)), LIST_OPLIST(list_int, M_BASIC_OPLIST)) { algo_list_sort_intersect(l1, l2); assert(list_int_equal_p (l1, l3)); } M_LET( (l1, 1, 4, 28, 29, 31, 34), (l2, 3, 32, 33), l3, LIST_OPLIST(list_int, M_BASIC_OPLIST)) { algo_list_sort_intersect(l1, l2); assert(list_int_equal_p (l1, l3)); } } static void test_array(void) { array_int_t l; array_int_init(l); for(int i = 0; i < 100; i++) array_int_push_back (l, i); assert( algo_array_contain_p(l, 62) == true); assert( algo_array_contain_p(l, -1) == false); assert( algo_array_sort_p(l) == true); assert (algo_array_all_of_p(l, func_test_42) == false); assert (algo_array_any_of_p(l, func_test_42) == true); assert (algo_array_none_of_p(l, func_test_42) == false); assert (algo_array_all_of_p(l, func_test_101) == false); assert (algo_array_any_of_p(l, func_test_101) == false); assert (algo_array_none_of_p(l, func_test_101) == true); assert (algo_array_all_of_p(l, func_test_pos) == true); assert (algo_array_any_of_p(l, func_test_pos) == true); assert (algo_array_none_of_p(l, func_test_pos) == false); assert( algo_array_count(l, 1) == 1); array_int_push_back (l, 17); assert( algo_array_count(l, 17) == 2); assert( algo_array_count(l, -1) == 0); assert( algo_array_sort_p(l) == false); assert( algo_array_count_if(l, func_test_42) == 1); assert( algo_array_count_if(l, func_test_101) == 0); array_int_it_t it; algo_array_find_last(it, l, 17); assert (!array_int_end_p (it)); assert (array_int_last_p (it)); algo_array_find_last(it, l, 1742); assert (array_int_end_p (it)); algo_array_find(it, l, 1742); assert (array_int_end_p (it)); #define f(x) assert((x) >= 0 && (x) < 100); ALGO_FOR_EACH(l, ARRAY_OPLIST(array_int), f); ALGO_FOR_EACH(l, array_int_t, f); g_min = 0; g_max = 99; g_count = 0; algo_array_for_each(l, g_f); assert(g_count == 101); int n; algo_array_reduce(&n, l, func_reduce); assert(n == 100*99/2+17); g_min = 0; g_max = 99; g_count = 0; algo_array_map_reduce(&n, l, func_reduce, func_map); assert(g_count == 101); assert(n == (328350 + 17*17)); M_LET(tmp, array_int_t) { g_count = 0; algo_array_transform(tmp, l, func_map); assert(g_count == 101); assert(array_int_size(tmp) == 101); for(int i = 0; i < 100; i++) { assert(*array_int_get(l, (size_t) i) == i); assert(*array_int_get(tmp, (size_t) i) == i * i); } assert(*array_int_get(l, 100) == 17); assert(*array_int_get(tmp, 100) == 17 * 17); array_int_reset(tmp); #define FT(d,x) ((d) = (x) + 1) ALGO_TRANSFORM(tmp, array_int_t, l, array_int_t, FT); assert(array_int_size(tmp) == 101); for(int i = 0; i < 100; i++) { assert(*array_int_get(l, (size_t) i) == i); assert(*array_int_get(tmp, (size_t) i) == i + 1); } array_int_reset(tmp); #define FT2(d,x,a) ((d) = (x) + (a)) ALGO_TRANSFORM(tmp, array_int_t, l, array_int_t, FT2, 17); assert(array_int_size(tmp) == 101); for(int i = 0; i < 100; i++) { assert(*array_int_get(l, (size_t) i) == i); assert(*array_int_get(tmp, (size_t) i) == i + 17); } } int *min, *max; assert (*algo_array_min(l) == 0); assert (*algo_array_max(l) == 99); algo_array_minmax(&min, &max, l); assert (*min == 0); assert (*max == 99); array_int_push_back (l, 1742); array_int_push_back (l, -17); assert (*algo_array_min(l) == -17); assert (*algo_array_max(l) == 1742); algo_array_minmax(&min, &max, l); assert (*min == -17); assert (*max == 1742); assert( algo_array_sort_p(l) == false); algo_array_sort(l); assert( algo_array_sort_p(l) == true); assert (array_int_size(l) == 103); algo_array_uniq(l); assert (array_int_size(l) == 102); assert( algo_array_sort_p(l) == true); M_LET(l2, array_int_t) { array_int_set(l2, l); array_int_it_t it1, it2; algo_array_mismatch(it1, it2, l, l2); assert (array_int_end_p (it1)); assert (array_int_end_p (it2)); array_int_pop_back(NULL, l2); array_int_push_back(l2, 159); algo_array_mismatch(it1, it2, l, l2); assert (!array_int_end_p (it1)); assert (!array_int_end_p (it2)); assert (*array_int_cref(it1) == 1742); assert (*array_int_cref(it2) == 159); algo_array_mismatch_if(it1, it2, l, l2, func_test_both_even_or_odd); assert (!array_int_end_p (it1)); assert (!array_int_end_p (it2)); assert (*array_int_cref(it1) == 1742); assert (*array_int_cref(it2) == 159); array_int_pop_back(NULL, l2); array_int_push_back(l2, 152); algo_array_mismatch_if(it1, it2, l, l2, func_test_both_even_or_odd); assert (array_int_end_p (it1)); assert (array_int_end_p (it2)); } array_int_reset(l); assert (algo_array_min(l) == NULL); assert (algo_array_max(l) == NULL); algo_array_minmax(&min, &max, l); assert (min == NULL); assert (max == NULL); assert (algo_array_sort_p(l) == true); algo_array_uniq(l); assert (array_int_size(l) == 0); assert( algo_array_sort_p(l) == true); for(int i = -14025; i < 324035; i+=17) array_int_push_back(l, i); for(int i = -14025; i < 324035; i+=7) array_int_push_back(l, i); assert( algo_array_sort_p(l) == false); array_int_special_stable_sort(l); assert( algo_array_sort_p(l) == true); array_int_clear(l); array_int_init(l); for(int i = 1; i <= 5; i++) array_int_push_back(l, i); assert (array_int_size(l) == 5); assert (algo_array_sort_p(l) == true); assert (algo_array_sort_dsc_p(l) == false); algo_array_sort_dsc(l); assert (algo_array_sort_p(l) == false); assert (algo_array_sort_dsc_p(l) == true); array_int_clear(l); M_LET( (arr, 1, 5, 34), array_int_t) { assert (array_int_size(arr) == 3); assert (algo_array_sort_p(arr) == true); assert (algo_array_sort_dsc_p(arr) == false); algo_array_fill(arr, 1789); assert(*array_int_get(arr, 0) == 1789); assert(*array_int_get(arr, 1) == 1789); assert(*array_int_get(arr, 2) == 1789); algo_array_fill_a(arr, 1789, 1); assert(*array_int_get(arr, 0) == 1789); assert(*array_int_get(arr, 1) == 1790); assert(*array_int_get(arr, 2) == 1791); algo_array_fill_a(arr, 0, 2); assert(*array_int_get(arr, 0) == 0); assert(*array_int_get(arr, 1) == 2); assert(*array_int_get(arr, 2) == 4); algo_array_fill_n(arr, 5, 1742); assert (array_int_size(arr) == 5); assert(*array_int_get(arr, 0) == 1742); assert(*array_int_get(arr, 1) == 1742); assert(*array_int_get(arr, 2) == 1742); assert(*array_int_get(arr, 3) == 1742); assert(*array_int_get(arr, 4) == 1742); algo_array_fill_an(arr, 4, -1, 3); assert (array_int_size(arr) == 4); assert(*array_int_get(arr, 0) == -1); assert(*array_int_get(arr, 1) == 2); assert(*array_int_get(arr, 2) == 5); assert(*array_int_get(arr, 3) == 8); } } static void test_string(void) { list_string_t l; list_string_init(l); string_t s; string_init_set_str(s, "Hello, World, John"); algo_string_split(l, s, ','); list_string_pop_back (&s, l); assert (string_equal_str_p(s, "Hello")); list_string_pop_back (&s, l); assert (string_equal_str_p(s, " World")); list_string_pop_back (&s, l); assert (string_equal_str_p(s, " John")); assert (list_string_empty_p(l)); string_set_str(s, "Hello,,John"); algo_string_split(l, s, ','); list_string_pop_back (&s, l); assert (string_equal_str_p(s, "Hello")); list_string_pop_back (&s, l); assert (string_equal_str_p(s, "")); list_string_pop_back (&s, l); assert (string_equal_str_p(s, "John")); assert (list_string_empty_p(l)); list_string_push_back (l, STRING_CTE("John")); list_string_push_back (l, STRING_CTE("Who")); list_string_push_back (l, STRING_CTE("Is")); algo_string_join(s, l, STRING_CTE("-")); // NOTE: List is reverse... Is-it really ok? assert (string_equal_str_p(s, "Is-Who-John")); string_clear(s); list_string_clear(l); M_LET( (a, (13, ("Jean") ),(14, ("Michael"))), array_person_t ) { assert( array_person_size(a) == 2); assert( (*array_person_get(a, 0))->age == 13 ); assert( string_equal_str_p( (*array_person_get(a, 0))->name, "Jean") ); assert( (*array_person_get(a, 1))->age == 14 ); assert( string_equal_str_p( (*array_person_get(a, 1))->name, "Michael") ); } } static void test_extract(void) { list_int_t l; list_int_init (l); for(int i = -100; i < 100; i++) list_int_push_back (l, i); list_int_reverse(l); array_int_t a; array_int_init(a); ALGO_EXTRACT(a, ARRAY_OPLIST(array_int), l, LIST_OPLIST(list_int)); assert(array_int_size(a) == 200); assert(*array_int_get(a, 0) == -100); assert(*array_int_get(a, 199) == 99); #define cond(d) ((d) > 0) ALGO_EXTRACT(a, ARRAY_OPLIST(array_int), l, LIST_OPLIST(list_int), cond); assert(array_int_size(a) == 99); assert(*array_int_get(a, 0) == 1); assert(*array_int_get(a, 98) == 99); #define cond2(c, d) ((d) > (c)) ALGO_EXTRACT(a, ARRAY_OPLIST(array_int), l, LIST_OPLIST(list_int), cond2, 10); assert(array_int_size(a) == 89); assert(*array_int_get(a, 0) == 11); assert(*array_int_get(a, 88) == 99); int dst = 0; #define inc(d, c) (d) += (c) ALGO_REDUCE(dst, a, ARRAY_OPLIST(array_int), inc); assert (dst == 100*99/2-10*11/2); ALGO_REDUCE(dst, a, array_int_t, inc); assert (dst == 100*99/2-10*11/2); #define sqr(d, c) (d) = (c)*(c) ALGO_REDUCE(dst, a, ARRAY_OPLIST(array_int), inc, sqr); assert (dst == 327965); #define sqr2(d, f, c) (d) = (f) * (c) ALGO_REDUCE(dst, a, ARRAY_OPLIST(array_int), inc, sqr2, 4); assert (dst == (100*99/2-10*11/2) *4 ); ALGO_REDUCE(dst, a, ARRAY_OPLIST(array_int), sum); assert (dst == 100*99/2-10*11/2); ALGO_REDUCE(dst, a, ARRAY_OPLIST(array_int), add); assert (dst == 100*99/2-10*11/2); ALGO_REDUCE(dst, a, ARRAY_OPLIST(array_int), and); assert (dst == 0); ALGO_REDUCE(dst, a, ARRAY_OPLIST(array_int), or); assert (dst == 127); unsigned long long dst_l = 0; // To avoid warnings about sign conversion between int and unsigned long long #define my_set(a, b) do { (a) = (unsigned int) (b); } while (0) #define my_sum(a, b) do { (a) += (unsigned int) (b); } while (0) ALGO_REDUCE( (dst_l, M_OPEXTEND(M_STANDARD_OPLIST, SET(my_set), TYPE(unsigned long long))), a, array_int_t, my_sum); assert (dst_l == 100*99/2-10*11/2); array_int_reset(a); for(int i = 1; i < 10; i++) array_int_push_back(a, i); ALGO_REDUCE(dst, a, ARRAY_OPLIST(array_int), product); assert (dst == 362880); array_int_clear(a); list_int_clear(l); M_LET(keys, array_int_t) M_LET( (m, (STRING_CTE("foo"), 1), (STRING_CTE("bar"), 42), (STRING_CTE("bluez"), 7), (STRING_CTE("stop"), 789) ), tmp, dict_int_t) { int s; /* Extract all elements of 'm' that starts with 'b' */ ALGO_EXTRACT(tmp, dict_int_t, m, dict_int_t, start_with, "b"); /* Extract the values of theses elements */ ALGO_TRANSFORM(keys, array_int_t, tmp, dict_int_t, get_value); /* Sum theses values */ ALGO_REDUCE(s, keys, array_int_t, sum); assert(s == 49); } } ARRAY_DEF(aint, int) LIST_DEF(lint, int) #define M_OPL_aint_t() ARRAY_OPLIST(aint) #define M_OPL_lint_t() LIST_OPLIST(lint) static void test_insert(void) { M_LET( (a, 1, 2, 3, 4), aint_t) M_LET( (b, -1, -2, -3), aint_t) { aint_it_t i; aint_it(i, a); // Insert it after first element of the array. ALGO_INSERT_AT(a, aint_t, i, b, aint_t); M_LET( (c, 1, -1, -2, -3, 2, 3, 4), aint_t) { assert (aint_equal_p (c, a)); } } M_LET( (a, 1, 2, 3, 4), lint_t) M_LET( (b, -1, -2, -3), aint_t) { lint_it_t i; lint_it(i, a); // Insert it after first element (aka back) ALGO_INSERT_AT(a, lint_t, i, b, aint_t); M_LET( (c, 1, -1, -2, -3, 2, 3, 4), lint_t) { assert (lint_equal_p (c, a)); } } M_LET( (a, 1, 2, 3, 4), lint_t) M_LET( (b, -1, -2, -3), lint_t) { lint_it_t i; lint_it(i, a); // Insert it after first element (aka back) ALGO_INSERT_AT(a, lint_t, i, b, lint_t); M_LET( (c, 1, -1, -2, -3, 2, 3, 4), lint_t) { assert (lint_equal_p (c, a)); } } } static void test_string_utf8(void) { M_LET( (s, ("H€llo René Chaînôr¬") ), string_t) M_LET( (ref, 72, 8364, 108, 108, 111, 32, 82, 101, 110, 233, 32, 67, 104, 97, 238, 110, 244, 114, 172), a, array_uint_t) { // Convert the string into an array of unicode. ALGO_EXTRACT(a, array_uint_t, s, string_t); // Compare the converted string into the reference array assert(array_uint_equal_p(a, ref)); } } /* Define some function objects */ FUNC_OBJ_INS_DEF(fo_test, algo_array_fo_test_obj, (a), { return a == self->x; }, (x, int)) #define M_OPL_fo_test_t() FUNC_OBJ_INS_OPLIST(fo_test, M_BASIC_OPLIST) FUNC_OBJ_INS_DEF(fo_eq, algo_array_fo_eq_obj, (a, b), { return a == b && self->x != a; }, (x, int)) #define M_OPL_fo_eq_t() FUNC_OBJ_INS_OPLIST(fo_eq, M_BASIC_OPLIST) FUNC_OBJ_INS_DEF(fo_cmp, algo_array_fo_cmp_obj, (a, b), { return a < b ? -self->x : a > b ? self->x : 0; }, (x, int)) #define M_OPL_fo_cmp_t() FUNC_OBJ_INS_OPLIST(fo_cmp, M_BASIC_OPLIST) FUNC_OBJ_INS_DEF(fol_cmp, algo_list_fo_cmp_obj, (a, b), { return a < b ? -self->x : a > b ? self->x : 0; }, (x, int)) #define M_OPL_fol_cmp_t() FUNC_OBJ_INS_OPLIST(fol_cmp, M_BASIC_OPLIST) static void test_fo(void) { M_LET(tab, array_int_t) { for(int i = 0; i < 10; i++) array_int_push_back(tab, i); array_int_push_back(tab, 5); array_int_it_t it; M_LET( (obj, 6), fo_test_t) algo_array_fo_find_fo(it, tab, fo_test_as_interface(obj)); assert(!array_int_end_p(it)); M_LET( (obj, 11), fo_test_t) algo_array_fo_find_fo(it, tab, fo_test_as_interface(obj)); assert(array_int_end_p(it)); M_LET( (obj, 11), fo_test_t) assert( 0 == algo_array_fo_count_fo(tab, fo_test_as_interface(obj))); M_LET( (obj, 5), fo_test_t) assert( 2 == algo_array_fo_count_fo(tab, fo_test_as_interface(obj))); M_LET( (obj, 3), fo_test_t) assert( false == algo_array_fo_all_of_fo_p(tab, fo_test_as_interface(obj))); M_LET( (obj, 3), fo_test_t) assert( true == algo_array_fo_any_of_fo_p(tab, fo_test_as_interface(obj))); M_LET( (obj, 3), fo_test_t) assert( false == algo_array_fo_none_of_fo_p(tab, fo_test_as_interface(obj))); M_LET( (obj, -1), fo_test_t) assert( true == algo_array_fo_none_of_fo_p(tab, fo_test_as_interface(obj))); array_int_push_back(tab, -1); M_LET( (obj, 1), fo_cmp_t) algo_array_fo_sort_fo(tab, fo_cmp_as_interface(obj)); M_LET ( (ref, -1, 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9), array_int_t) assert( array_int_equal_p(tab, ref)); } M_LET(tab, LIST_OPLIST(list_int)) { for(int i = 0; i < 10; i++) list_int_push_back(tab, i); list_int_push_back(tab, 5); list_int_push_back(tab, -1); M_LET( (obj, 1), fol_cmp_t) algo_list_fo_sort_fo(tab, fol_cmp_as_interface(obj)); M_LET ( (ref, -1, 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9), LIST_OPLIST(list_int)) { assert( list_int_equal_p(tab, ref)); } } } int main(void) { test_list(); test_array(); test_string(); test_extract(); test_insert(); test_string_utf8(); test_fo(); testobj_final_check(); exit(0); }