/* * 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 "test-obj.h" #include "m-dict.h" #include "m-array.h" #include "m-string.h" #include "coverage.h" static inline bool oor_equal_p(int k, unsigned char n) { return k == (int)-n-1; } static inline void oor_set(int *k, unsigned char n) { *k = (int)-n-1; } static inline void update_value (int *p, const int p1, const int p2) { *p = p1 + p2; } START_COVERAGE DICT_DEF2(dict_str, string_t, STRING_OPLIST, string_t, STRING_OPLIST) DICT_OA_DEF2(dict_oa_int, int, M_OPEXTEND(M_BASIC_OPLIST, OOR_EQUAL(oor_equal_p), OOR_SET(oor_set M_IPTR)), int, M_OPEXTEND(M_BASIC_OPLIST, ADD(update_value M_IPTR))) END_COVERAGE DICT_SET_DEF(dict_setstr, string_t, STRING_OPLIST) DICT_DEF2(dict_int, int, M_BASIC_OPLIST, int, M_BASIC_OPLIST) DICT_DEF2(dict_mpz, string_t, STRING_OPLIST, testobj_t, TESTOBJ_OPLIST) BOUNDED_STRING_DEF(symbol, 15) DICT_OA_DEF2(dict_oa_str, symbol_t, BOUNDED_STRING_OPLIST(symbol), int, M_BASIC_OPLIST) DICT_OA_DEF2(dict_oa_bstr, string_t, STRING_OPLIST, int, M_BASIC_OPLIST) DICT_OASET_DEF(dict_oa_setstr, string_t, STRING_OPLIST) DICT_DEF2_AS(dictas_int, DictInt, DictIntIt, DictIntItRef, int, M_BASIC_OPLIST, int, M_BASIC_OPLIST) DICT_STOREHASH_DEF2_AS(dictas_str2, DictSInt, DictSIntIt, DictSIntItRef, string_t, STRING_OPLIST, string_t, STRING_OPLIST) DICT_SET_DEF_AS(dictas_setstr, DictStr, DictStrIt, string_t, STRING_OPLIST) DICT_OA_DEF2_AS(dictas_oa_bstr, DictOAStr, DictOAStrIt, DictOAStrItRef, string_t, STRING_OPLIST, int, M_BASIC_OPLIST) DICT_OASET_DEF_AS(dictas_oa_setstr, DictOASStr, DictOASStrIt, string_t, STRING_OPLIST) /* Helper structure */ ARRAY_DEF(array_string, string_t, STRING_OPLIST) array_string_t v_str; static void init_data(int data_size) { uint32_t x = 11; string_t s; string_init (s); array_string_init(v_str); for (int i = 0; i < data_size; ++i) { unsigned int j = (unsigned int)(data_size * ((double)x / UINT_MAX) / 4) * 271828183u; string_printf(s, "%x", j); array_string_push_back (v_str, s); x = (uint32_t) (1664525L * x + 1013904223L); } string_clear(s); } static void clear_data(void) { array_string_clear(v_str); } static void test_data(void) { dict_str_t dict; int data_size = (int) array_string_size(v_str); dict_str_init (dict); assert(dict_str_empty_p(dict)); for (int i = 0; i < data_size; ++i) { dict_str_set_at(dict, *array_string_cget(v_str, (size_t) i), *array_string_cget(v_str, (size_t) ((i+1) % data_size))); assert(!dict_str_empty_p(dict)); } assert(dict_str_size(dict) == 1227176); dict_str_t dict2; dict_str_init (dict2); dict_str_swap (dict, dict2); assert(dict_str_size(dict) == 0); assert(dict_str_size(dict2) == 1227176); dict_str_clear (dict2); dict_str_clear (dict); } static void check_io(void) { M_LET(str, STRING_OPLIST) M_LET(dict, dict2, DICT_OPLIST(dict_str)) { dict_str_get_str(str, dict, false); assert (string_cmp_str (str, "{}") == 0); const char *sp; bool b = dict_str_parse_str(dict2, string_get_cstr(str), &sp); assert (b); assert (*sp == 0); assert (dict_str_equal_p(dict, dict2)); dict_str_set_at (dict, STRING_CTE("LICENCE"), STRING_CTE("BSD3")); dict_str_get_str(str, dict, false); assert (string_cmp_str (str, "{\"LICENCE\":\"BSD3\"}") == 0); dict_str_set_at (dict, STRING_CTE("AUTHOR"), STRING_CTE("PP")); dict_str_get_str(str, dict, false); //NOTE: order is dependent on the hash system. assert (string_cmp_str (str, "{\"LICENCE\":\"BSD3\",\"AUTHOR\":\"PP\"}") == 0 || string_cmp_str (str, "{\"AUTHOR\":\"PP\",\"LICENCE\":\"BSD3\"}") == 0); b = dict_str_parse_str(dict2, string_get_cstr(str), &sp); assert (b); assert (*sp == 0); assert (dict_str_equal_p(dict, dict2)); string_set_str (str, "{ \"LICENCE\" :\"BSD3\" , \"AUTHOR\" :\"PP\" }"); b = dict_str_parse_str(dict2, string_get_cstr(str), &sp); assert (b); assert (*sp == 0); assert (dict_str_equal_p(dict, dict2)); string_set_str (str, " { \"LICENCE\" : \"BSD3\" , \"AUTHOR\" :\"PP\" } "); b = dict_str_parse_str(dict2, string_get_cstr(str), &sp); assert (b); assert (*sp == ' '); assert (dict_str_equal_p(dict, dict2)); FILE *f = m_core_fopen ("a-mdict.dat", "wt"); if (!f) abort(); dict_str_out_str(f, dict); fclose (f); f = m_core_fopen ("a-mdict.dat", "rt"); if (!f) abort(); b = dict_str_in_str(dict2, f); assert (b == true); assert (dict_str_equal_p (dict, dict2)); fclose (f); f = m_core_fopen ("a-mdict.dat", "wt"); if (!f) abort(); fprintf (f, " { \"LICENCE\" : \"BSD3\" , \"AUTHOR\" :\"PP\" } "); fclose (f); f = m_core_fopen ("a-mdict.dat", "rt"); if (!f) abort(); b = dict_str_in_str(dict2, f); assert (b == true); assert (dict_str_equal_p (dict, dict2)); fclose (f); f = m_core_fopen ("a-mdict.dat", "wt"); if (!f) abort(); fprintf (f, "AA"); fclose (f); f = m_core_fopen ("a-mdict.dat", "rt"); if (!f) abort(); b = dict_str_in_str(dict2, f); assert (!b); fclose (f); f = m_core_fopen ("a-mdict.dat", "wt"); if (!f) abort(); fprintf (f, "{"); fclose (f); f = m_core_fopen ("a-mdict.dat", "rt"); if (!f) abort(); b = dict_str_in_str(dict2, f); assert (!b); fclose (f); f = m_core_fopen ("a-mdict.dat", "wt"); if (!f) abort(); fprintf (f, "{}"); fclose (f); f = m_core_fopen ("a-mdict.dat", "rt"); if (!f) abort(); b = dict_str_in_str(dict2, f); assert (b); assert(dict_str_empty_p(dict2)); fclose (f); f = m_core_fopen ("a-mdict.dat", "wt"); if (!f) abort(); fprintf (f, "{\"X\""); fclose (f); f = m_core_fopen ("a-mdict.dat", "rt"); if (!f) abort(); b = dict_str_in_str(dict2, f); assert (!b); fclose (f); f = m_core_fopen ("a-mdict.dat", "wt"); if (!f) abort(); fprintf (f, "{\"X\","); fclose (f); f = m_core_fopen ("a-mdict.dat", "rt"); if (!f) abort(); b = dict_str_in_str(dict2, f); assert (!b); fclose (f); f = m_core_fopen ("a-mdict.dat", "wt"); if (!f) abort(); fprintf (f, "{X:T}"); fclose (f); f = m_core_fopen ("a-mdict.dat", "rt"); if (!f) abort(); b = dict_str_in_str(dict2, f); assert (!b); fclose (f); f = m_core_fopen ("a-mdict.dat", "wt"); if (!f) abort(); fprintf (f, "{\"X\":"); fclose (f); f = m_core_fopen ("a-mdict.dat", "rt"); if (!f) abort(); b = dict_str_in_str(dict2, f); assert (!b); fclose (f); f = m_core_fopen ("a-mdict.dat", "wt"); if (!f) abort(); fprintf (f, "{\"X\":Y"); fclose (f); f = m_core_fopen ("a-mdict.dat", "rt"); if (!f) abort(); b = dict_str_in_str(dict2, f); assert (!b); fclose (f); f = m_core_fopen ("a-mdict.dat", "wt"); if (!f) abort(); fprintf (f, "{\"X\":\"Y\""); fclose (f); f = m_core_fopen ("a-mdict.dat", "rt"); if (!f) abort(); b = dict_str_in_str(dict2, f); assert (!b); fclose (f); f = m_core_fopen ("a-mdict.dat", "wt"); if (!f) abort(); fprintf (f, "{\"X\":\"Y\","); fclose (f); f = m_core_fopen ("a-mdict.dat", "rt"); if (!f) abort(); b = dict_str_in_str(dict2, f); assert (!b); fclose (f); string_set_str (str, " { } "); b = dict_str_parse_str(dict2, string_get_cstr(str), &sp); assert (b); assert (*sp == ' '); assert (dict_str_size(dict2) == 0); string_set_str (str, " [ } "); b = dict_str_parse_str(dict2, string_get_cstr(str), &sp); assert (!b); string_set_str (str, " { ] "); b = dict_str_parse_str(dict2, string_get_cstr(str), &sp); assert (!b); string_set_str (str, " { \"LICENCE\" : \"BSD3\" "); b = dict_str_parse_str(dict2, string_get_cstr(str), &sp); assert (!b); string_set_str (str, " { \"LICENCE\" :"); b = dict_str_parse_str(dict2, string_get_cstr(str), &sp); assert (!b); string_set_str (str, " { \"LICENCE\""); b = dict_str_parse_str(dict2, string_get_cstr(str), &sp); assert (!b); string_set_str (str, " { "); b = dict_str_parse_str(dict2, string_get_cstr(str), &sp); assert (!b); } } static void test_set(void) { M_LET(str, STRING_OPLIST) M_LET(set, DICT_SET_OPLIST(dict_setstr, STRING_OPLIST)) { for(int i = 0; i < 100; i++) { string_printf(str, "%d", i); dict_setstr_push(set, str); } assert(dict_setstr_size(set) == 100); for(int i = 0; i < 100; i++) { string_printf(str, "%d", i); string_t *p = dict_setstr_get(set, str); assert (p != NULL); assert(string_equal_p (*p, str)); p = dict_setstr_safe_get(set, str); assert (p != NULL); assert(string_equal_p (*p, str)); } assert(dict_setstr_size(set) == 100); } } static void test_init(void) { M_LET(str1, str2, STRING_OPLIST) M_LET(d1, d2, DICT_OPLIST(dict_str, STRING_OPLIST, STRING_OPLIST)){ for(int i = 0; i < 100; i++) { string_printf(str1, "%d", 2*i); string_printf(str2, "%d", 2*i+1); dict_str_set_at (d1, str1, str2); } assert (dict_str_size (d1) == 100); for(int i = 0; i < 100; i++) { string_printf(str1, "%d", 2*i); string_printf(str2, "%d", 2*i+1); string_t *p = dict_str_get (d1, str1); assert (p != NULL); assert (string_equal_p(*p, str2)); p = dict_str_safe_get (d1, str1); assert (p != NULL); assert (string_equal_p(*p, str2)); } dict_str_t d3; dict_str_init_set (d3, d1); assert (dict_str_equal_p (d3, d1)); dict_str_set (d2, d1); assert (dict_str_equal_p (d2, d1)); assert (dict_str_equal_p (d2, d3)); dict_str_clear (d3); dict_str_set_at (d1, STRING_CTE("x"), STRING_CTE("y")); assert (dict_str_size (d1) == 101); assert (!dict_str_equal_p (d2, d1)); bool b = dict_str_erase (d1, STRING_CTE("0")); assert (dict_str_size (d1) == 100); assert (b); assert (!dict_str_equal_p (d2, d1)); for(int i = 1; i < 100; i++) { string_printf(str1, "%d", 2*i); b = dict_str_erase (d1, str1); assert (b); } assert (dict_str_size (d1) == 1); dict_str_swap (d1, d2); assert (dict_str_size (d1) == 100); assert (dict_str_size (d2) == 1); assert (string_equal_str_p (*dict_str_get (d2, STRING_CTE("x")), "y")); assert (dict_str_get (d2, STRING_CTE("y")) == NULL); dict_str_init_move (d3, d1); assert (dict_str_size (d3) == 100); for(int i = 0; i < 100; i++) { string_printf(str1, "%d", 2*i); string_printf(str2, "%d", 2*i+1); assert (string_equal_p (*dict_str_get (d3, str1), str2)); } dict_str_init_set (d1, d3); assert (dict_str_size (d1) == 100); dict_str_move (d2, d3); assert (dict_str_size (d2) == 100); dict_str_reset (d2); assert (dict_str_size (d2) == 0); assert (dict_str_size (d1) == 100); for(int i = 100; i < 200; i++) { string_printf(str1, "%d", 2*i); string_printf(*dict_str_safe_get (d1, str1), "%d", 2*i+1); } assert (dict_str_size (d1) == 200); for(int i = 100; i < 200; i++) { string_printf(str1, "%d", 2*i); string_printf(str2, "%d", 2*i+1); string_t *p = dict_str_get (d1, str1); assert (p != NULL); assert (string_equal_p(*p, str2)); p = dict_str_safe_get (d1, str1); assert (p != NULL); assert (string_equal_p(*p, str2)); } dict_str_reset(d1); dict_str_reset(d2); assert (dict_str_equal_p (d2, d1)); dict_str_set_at (d1, STRING_CTE("X"), STRING_CTE("2")); dict_str_set_at (d2, STRING_CTE("X"), STRING_CTE("3")); assert (!dict_str_equal_p (d2, d1)); dict_str_set_at (d2, STRING_CTE("X"), STRING_CTE("2")); assert (dict_str_equal_p (d2, d1)); dict_str_reserve(d1, 0); dict_str_equal_p (d2, d1); dict_str_reserve(d2, 4000); dict_str_equal_p (d2, d1); } // Create some items, delete some, create others, delete all M_LET(str1, str2, STRING_OPLIST) M_LET(d1, DICT_OPLIST(dict_str, STRING_OPLIST, STRING_OPLIST)){ for(int s = 32; s < 5000; s++) { for(int i = 0; i < s; i++) { string_printf(str1, "%d", 2*i); string_printf(str2, "%d", 2*i+1); dict_str_set_at (d1, str1, str2); } for(int i = 0; i < s; i+=5) { string_printf(str1, "%d", 2*i); bool b = dict_str_erase (d1, str1); assert (b); b = dict_str_erase (d1, str1); assert (!b); } for(int i = 0; i < s; i++) { string_printf(str1, "%d", 2*i); string_t *p = dict_str_get (d1, str1); if ( (i%5) == 0) { assert(p == NULL); } else { assert (p != NULL); string_printf(str2, "%d", 2*i+1); assert( string_equal_p (*p, str2)); } } for(int i = 0; i < s; i+=5) { string_printf(str1, "%d", 2*i); string_printf(str2, "%d", 2*i+1); dict_str_set_at (d1, str1, str2); } for(int i = 1; i < s; i+=5) { string_printf(str1, "%d", 2*i); bool b = dict_str_erase (d1, str1); assert (b); } for(int i = 1; i < s; i+=5) { string_printf(str1, "%d", 2*i); string_printf(str2, "%d", 2*i+1); string_set( *dict_str_safe_get(d1, str1), str2); } for(int i = 0; i < s; i++) { string_printf(str1, "%d", 2*i); bool b = dict_str_erase (d1, str1); assert (b); } assert(dict_str_empty_p(d1)); } } M_LET( (d1, (STRING_CTE("H1"), STRING_CTE("EE")), (("H2"), ("EF"))), DICT_OPLIST(dict_str, STRING_OPLIST, STRING_OPLIST)){ string_t * p = dict_str_get(d1, STRING_CTE("H1")); assert( p != NULL ); assert(string_equal_str_p(*p, "EE")); p = dict_str_get(d1, STRING_CTE("H2")); assert( p != NULL ); assert(string_equal_str_p(*p, "EF")); } M_LET( (d1, (("H1"), STRING_CTE("EE")), (STRING_CTE("H2"), ("EF"))), DICT_OPLIST(dict_str, STRING_OPLIST, STRING_OPLIST)){ string_t * p = dict_str_get(d1, STRING_CTE("H1")); assert( p != NULL ); assert(string_equal_str_p(*p, "EE")); p = dict_str_get(d1, STRING_CTE("H2")); assert( p != NULL ); assert(string_equal_str_p(*p, "EF")); } } // this test generates dict equal but with different physical representation static void test_equal(void) { for(int n = 10 ; n < 500; n+=2) { M_LET(str1, str2, string_t) M_LET(d1, d2, DICT_OPLIST(dict_str, STRING_OPLIST, STRING_OPLIST)){ for(int i = 0 ; i < n; i++) { string_printf(str1, "%d", i); dict_str_set_at(d1, str1, str1); } for(int i = 0 ; i < n; i++) { string_printf(str1, "%d", i); dict_str_set_at(d2, str1, str1); string_printf(str1, "%d", n-1-i); dict_str_erase(d1, str1); assert(dict_str_equal_p(d1, d2) == ((i+1) == (n+1)/2)); assert(dict_str_equal_p(d2, d1) == ((i+1) == (n+1)/2)); } } } } static void test1(void) { dict_str_t dict; string_t key, ref; dict_str_init(dict); string_init(key); string_init(ref); FILE *f = m_core_fopen("dict.txt", "rt"); if (!f) abort(); dict_str_set_at(dict, STRING_CTE("LICENCE"), STRING_CTE("BSD3")); assert(string_equal_p(*dict_str_cget(dict, STRING_CTE("LICENCE")), STRING_CTE("BSD3"))); while (!feof(f) && !ferror(f)) { string_fgets(key, f, STRING_READ_PURE_LINE); size_t idx = string_search_char(key, ':'); string_set(ref, key); string_right(ref, idx+1); string_left(key, idx); dict_str_set_at (dict, key, ref); } fclose(f); assert(dict_str_size(dict) == 19); f = m_core_fopen("dict.txt", "rt"); if (!f) abort(); while (!feof(f) && !ferror(f)) { string_fgets(key, f, STRING_READ_PURE_LINE); size_t idx = string_search_char(key, ':'); string_set(ref, key); string_right(ref, idx+1); string_left(key, idx); string_t *ptr = dict_str_get (dict, key); assert(ptr != NULL); assert(string_equal_p (*ptr, ref) || string_cmp_str(ref, "lisez-moi") == 0); } fclose(f); dict_str_set_at(dict, STRING_CTE("LICENCE"), STRING_CTE("BSD3")); assert(dict_str_size(dict) == 19); dict_str_set_at(dict, STRING_CTE("LICENCE"), STRING_CTE("BSD3")); assert(dict_str_size(dict) == 19); size_t s = 0; bool check1 = false, check2= false; for M_EACH(r, dict, DICT_OPLIST(dict_str)) { if (string_cmp_str(r->key, "README") == 0) check1 = true; if (string_cmp_str(r->value, "BSD3") == 0) check2 = true; s++; } assert(s == 19); assert(check1); assert(check2); string_clear(key); string_clear(ref); dict_str_clear(dict); check_io(); init_data(5000000); test_data(); clear_data(); } static void test_oa(void) { dict_oa_int_t d; dict_oa_int_init(d); for(int i = 0 ; i < 150; i+= 3) dict_oa_int_set_at(d, i, i*i); assert(dict_oa_int_size(d) == 50); for(int i = 0 ; i < 150; i++) { int *p = dict_oa_int_get(d, i); if ((i % 3) == 0) { assert (p != NULL); assert (*p == i*i); } else { assert (p == NULL); } } assert(dict_oa_int_size(d) == 50); for(int i = 1 ; i < 150; i+= 3) *dict_oa_int_safe_get(d, i) = i*i; assert(dict_oa_int_size(d) == 100); for(int i = 0 ; i < 150; i++) { int *p = dict_oa_int_get(d, i); if ((i % 3) != 2) { assert (p != NULL); assert (*p == i*i); } else { assert (p == NULL); } } assert(dict_oa_int_size(d) == 100); dict_oa_int_clear(d); } static void test_init_oa(void) { M_LET(d1, d2, DICT_OPLIST(dict_oa_int, M_BASIC_OPLIST, M_BASIC_OPLIST)){ assert (dict_oa_int_equal_p (d2, d1)); bool b= dict_oa_int_erase (d1, 17); assert(!b); for(int i = 0; i < 100; i++) { dict_oa_int_set_at (d1, 2*i, 2*i+1); } assert (dict_oa_int_size (d1) == 100); b= dict_oa_int_erase (d1, 17); assert(!b); dict_oa_int_set_at (d1, 17, 42); b= dict_oa_int_erase (d1, 17); assert(b); b= dict_oa_int_erase (d1, 17); assert(!b); dict_oa_int_t d3; dict_oa_int_init_set (d3, d1); assert (dict_oa_int_equal_p (d3, d1)); dict_oa_int_set (d2, d1); assert (dict_oa_int_get (d2, -10) == NULL); assert (*dict_oa_int_get (d2, 10) == 11); assert (dict_oa_int_equal_p (d2, d1)); assert (dict_oa_int_equal_p (d2, d3)); assert (dict_oa_int_equal_p (d1, d3)); dict_oa_int_clear (d3); dict_oa_int_set_at (d1, -10, -20); assert (dict_oa_int_size (d1) == 101); assert (*dict_oa_int_get (d1, -10) == -20); dict_oa_int_set_at (d1, -10, -22); assert (dict_oa_int_size (d1) == 101); assert (*dict_oa_int_get (d1, -10) == -22); assert (!dict_oa_int_equal_p (d2, d1)); b = dict_oa_int_erase (d1, 0); assert (dict_oa_int_size (d1) == 100); assert (b); assert (!dict_oa_int_equal_p (d2, d1)); for(int i = 1; i < 100; i++) { b = dict_oa_int_erase (d1, 2*i); assert (b); } for(int max = 1000; max < 10000; max+= 500) { for(int del = max/2 ; del < max ; del += 100) { for(int i = 1; i < max; i++) { dict_oa_int_set_at(d1, 1000+i, -1); assert (*dict_oa_int_get (d1, 1000+i) == -1); dict_oa_int_set_at(d1, 1000+i, -2); assert (*dict_oa_int_get (d1, 1000+i) == -2); } for(int i = 1; i < del; i++) { assert (*dict_oa_int_get (d1, 1000+i) == -2); assert (*dict_oa_int_safe_get (d1, 1000+i) == -2); b = dict_oa_int_erase (d1, 1000+i); assert (b); } for(int i = 1; i < max; i++) { dict_oa_int_set_at(d1, 1000+i, -2); assert (*dict_oa_int_get (d1, 1000+i) == -2); } for(int i = 1; i < max; i++) { assert (*dict_oa_int_get (d1, 1000+i) == -2); assert (*dict_oa_int_safe_get (d1, 1000+i) == -2); b = dict_oa_int_erase (d1, 1000+i); assert (b); } for(int i = 1; i < max; i++) { *dict_oa_int_safe_get (d1, 1000+i) = -3; } for(int i = 1; i < del; i++) { assert (*dict_oa_int_safe_get (d1, 1000+i) == -3); b = dict_oa_int_erase (d1, 1000+i); assert (b); } for(int i = 1; i < max; i++) { *dict_oa_int_safe_get (d1, 1000+i) = -3; } for(int i = 1; i < max; i++) { assert (*dict_oa_int_get (d1, 1000+i) == -3); b = dict_oa_int_erase (d1, 1000+i); assert (b); } } } assert (dict_oa_int_size (d1) == 1); dict_oa_int_swap (d1, d2); assert (dict_oa_int_size (d1) == 100); assert (dict_oa_int_size (d2) == 1); assert (*dict_oa_int_get (d2, -10) == -22); assert (dict_oa_int_get (d2, -20) == NULL); dict_oa_int_init_move (d3, d1); assert (dict_oa_int_size (d3) == 100); for(int i = 0; i < 100; i++) { assert (*dict_oa_int_get (d3, 2*i) == 2*(int)i+1); } dict_oa_int_init_set (d1, d3); assert (dict_oa_int_size (d1) == 100); dict_oa_int_move (d2, d3); assert (dict_oa_int_size (d2) == 100); dict_oa_int_reset (d2); assert (dict_oa_int_size (d2) == 0); dict_oa_int_reset(d1); dict_oa_int_reset(d2); dict_oa_int_set_at(d1, 1, 2); assert (!dict_oa_int_equal_p (d1, d2)); dict_oa_int_set_at(d2, 1, 2); assert (dict_oa_int_equal_p (d1, d2)); dict_oa_int_set_at(d2, 1, 3); assert (!dict_oa_int_equal_p (d1, d2)); } M_LET( (d1, (1, 2), (2, 3), (4, 5)), (d2, (1, 3), (4, 7), (10, 14)), (r1, (1, 5), (2, 3), (4, 12), (10, 14) ), DICT_OPLIST(dict_oa_int, M_BASIC_OPLIST, M_BASIC_OPLIST)) { dict_oa_int_splice(d1, d2); assert(dict_oa_int_equal_p(d1, r1)); assert(dict_oa_int_empty_p(d2)); } } static void test_it_oa(void) { M_LET(d1, DICT_OPLIST(dict_oa_int, M_BASIC_OPLIST, M_BASIC_OPLIST)){ dict_oa_int_it_t it0; dict_oa_int_it(it0, d1); assert( dict_oa_int_end_p(it0) ); dict_oa_int_it_last(it0, d1); assert( dict_oa_int_end_p(it0) ); dict_oa_int_it_end(it0, d1); assert( dict_oa_int_end_p(it0) ); for(int i = 0; i < 100; i++) { dict_oa_int_set_at (d1, 2*i, 2*i+1); } assert (dict_oa_int_size (d1) == 100); dict_oa_int_it_t it; size_t s = 0; for(dict_oa_int_it(it, d1); !dict_oa_int_end_p(it); dict_oa_int_next(it)) { dict_oa_int_itref_t *pair = dict_oa_int_ref(it); assert (pair->key >= 0 && pair->key < 200); assert (pair->value == pair->key + 1); s++; } assert (s == 100); dict_oa_int_it_end(it, d1); assert (dict_oa_int_end_p(it)); assert (dict_oa_int_last_p(it)); dict_oa_int_previous(it); assert (!dict_oa_int_end_p(it)); assert (dict_oa_int_last_p(it)); dict_oa_int_it_t it2; dict_oa_int_it_last(it2, d1); assert (dict_oa_int_it_equal_p(it2, it)); dict_oa_int_it(it2, d1); dict_oa_int_it_set(it2, it); assert (dict_oa_int_it_equal_p(it2, it)); dict_oa_int_previous(it2); assert (!dict_oa_int_it_equal_p(it2, it)); dict_oa_int_next(it2); assert (dict_oa_int_it_equal_p(it2, it)); s = 0; for(dict_oa_int_it_last(it, d1); !dict_oa_int_end_p(it); dict_oa_int_previous(it)) { dict_oa_int_itref_t *pair = dict_oa_int_ref(it); assert (pair->key >= 0 && pair->key < 200); assert (pair->value == pair->key + 1); s++; } assert (s == 100); } } static void test_oa_str1(void) { symbol_t s; int *p; dict_oa_str_t dict; symbol_init(s); dict_oa_str_init(dict); dict_oa_str_set_at(dict, BOUNDED_STRING_CTE(symbol, "x"), 1); dict_oa_str_set_at(dict, BOUNDED_STRING_CTE(symbol, "y"), 2); dict_oa_str_set_at(dict, BOUNDED_STRING_CTE(symbol, "z"), 3); p = dict_oa_str_safe_get(dict, BOUNDED_STRING_CTE(symbol, "x")); assert(p != NULL); assert(*p == 1); dict_oa_str_clear(dict); symbol_clear(s); } static void test_oa_str2(void) { int *p; dict_oa_bstr_t dict; dict_oa_bstr_init(dict); dict_oa_bstr_set_at(dict, STRING_CTE("x"), 1); dict_oa_bstr_set_at(dict, STRING_CTE("y"), 2); dict_oa_bstr_set_at(dict, STRING_CTE("z"), 3); p = dict_oa_bstr_safe_get(dict, STRING_CTE("x")); assert(p != NULL); assert(*p == 1); dict_oa_bstr_clear(dict); } static void test_emplace (void) { dict_mpz_t d; dict_mpz_init(d); string_t s; string_init(s); dict_mpz_emplace_key_val_str(d, "HELLO", "14"); string_set_str(s, "HELLO"); testobj_t *ptr = dict_mpz_get(d, s); assert(ptr != NULL); assert(testobj_cmp_ui(*ptr, 14) == 0); dict_mpz_emplace_key_val_ui(d, "HE", 145); string_set_str(s, "HE"); ptr = dict_mpz_get(d, s); assert(ptr != NULL); assert(testobj_cmp_ui(*ptr, 145) == 0); dict_mpz_emplace_key_val(d, "SHE", *ptr); string_set_str(s, "SHE"); ptr = dict_mpz_get(d, s); assert(ptr != NULL); assert(testobj_cmp_ui(*ptr, 145) == 0); dict_mpz_emplace_key(d, "IT", *ptr); string_set_str(s, "IT"); ptr = dict_mpz_get(d, s); assert(ptr != NULL); assert(testobj_cmp_ui(*ptr, 145) == 0); dict_mpz_emplace_val_ui(d, s, 19); ptr = dict_mpz_get(d, s); assert(ptr != NULL); assert(testobj_cmp_ui(*ptr, 19) == 0); dict_mpz_emplace_val_str(d, s, "190"); ptr = dict_mpz_get(d, s); assert(ptr != NULL); assert(testobj_cmp_ui(*ptr, 190) == 0); dict_mpz_emplace_key(d, "IT", *ptr); ptr = dict_mpz_get_emplace(d, "IT"); assert(ptr != NULL); assert(testobj_cmp_ui(*ptr, 190) == 0); dict_mpz_emplace_key_val_str(d, "SHE", "189"); ptr = dict_mpz_get_emplace(d, "SHE"); assert(ptr != NULL); assert(testobj_cmp_ui(*ptr, 189) == 0); string_clear(s); dict_mpz_clear(d); } static void test_coverage(void) { // Call of the utilities functions, so that they do not impact the coverage dict_oa_int_array_pair_t v; dict_oa_int_array_pair_init(v); dict_oa_int_pair_ct arg = { 23, 23 }; dict_oa_int_array_pair_push_back(v, arg); dict_oa_int_array_pair_reset(v); dict_oa_int_array_pair_clear(v); } int main(void) { test1(); test_set(); test_init(); test_equal(); test_emplace(); test_oa(); test_init_oa(); test_it_oa(); test_oa_str1(); test_oa_str2(); testobj_final_check(); test_coverage(); exit(0); }