|    834         cxMapPut(s1, s1_keys[i], &s1_values[i]); | 
   834         cxMapPut(s1, s1_keys[i], &s1_values[i]); | 
|    835         cxMapPut(s2, s2_keys[i], &s2_values[i]); | 
   835         cxMapPut(s2, s2_keys[i], &s2_values[i]); | 
|    836     } | 
   836     } | 
|    837     CX_TEST_DO { | 
   837     CX_TEST_DO { | 
|    838         int c = 4; | 
   838         int c = 4; | 
|    839         test_hash_map_clone_func_max_clones = 100; // no limit | 
        | 
|    840         CX_TEST_ASSERT(0 == cxMapDifference(dst, s1, s2, test_hash_map_clone_func, allocator, &c)); | 
   839         CX_TEST_ASSERT(0 == cxMapDifference(dst, s1, s2, test_hash_map_clone_func, allocator, &c)); | 
|    841         CX_TEST_ASSERT(cxMapSize(dst) == 2); | 
   840         CX_TEST_ASSERT(cxMapSize(dst) == 2); | 
|    842         CX_TEST_ASSERT(*((int*)cxMapGet(dst, "k1")) == 5); | 
   841         CX_TEST_ASSERT(*((int*)cxMapGet(dst, "k1")) == 5); | 
|    843         CX_TEST_ASSERT(cxMapGet(dst, "k2") == NULL); | 
   842         CX_TEST_ASSERT(cxMapGet(dst, "k2") == NULL); | 
|    844         CX_TEST_ASSERT(*((int*)cxMapGet(dst, "k3")) == 8); | 
   843         CX_TEST_ASSERT(*((int*)cxMapGet(dst, "k3")) == 8); | 
|    845  | 
   844  | 
|    846         cxMapClear(dst); | 
   845         cxMapClear(dst); | 
|    847         CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); | 
   846         CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); | 
|         | 
   847     } | 
|         | 
   848     cxMapFree(dst); | 
|         | 
   849     cxMapFree(s1); | 
|         | 
   850     cxMapFree(s2); | 
|         | 
   851     cx_testing_allocator_destroy(&talloc); | 
|         | 
   852 } | 
|         | 
   853  | 
|         | 
   854 CX_TEST(test_hash_map_intersection) { | 
|         | 
   855     CxMap *dst = cxHashMapCreateSimple(sizeof(int)); | 
|         | 
   856  | 
|         | 
   857     CxMap *s1 = cxHashMapCreateSimple(CX_STORE_POINTERS); | 
|         | 
   858     CxMap *s2 = cxHashMapCreateSimple(CX_STORE_POINTERS); | 
|         | 
   859     const char *s1_keys[] = {"k1", "k2", "k3", "k4"}; | 
|         | 
   860     int s1_values[] = {1, 3, 4, 6}; | 
|         | 
   861     const char *s2_keys[] = {"k4", "k5", "k2", "k6"}; | 
|         | 
   862     int s2_values[] = {5, 9, 15, 23}; | 
|         | 
   863     for (unsigned int i = 0 ; i < 4 ; i++) { | 
|         | 
   864         cxMapPut(s1, s1_keys[i], &s1_values[i]); | 
|         | 
   865         cxMapPut(s2, s2_keys[i], &s2_values[i]); | 
|         | 
   866     } | 
|         | 
   867     CX_TEST_DO { | 
|         | 
   868         int c = 4; | 
|         | 
   869         CX_TEST_ASSERT(0 == cxMapIntersection(dst, s1, s2, test_hash_map_clone_func, NULL, &c)); | 
|         | 
   870         CX_TEST_ASSERT(cxMapSize(dst) == 2); | 
|         | 
   871         CX_TEST_ASSERT(*((int*)cxMapGet(dst, "k2")) == 7); | 
|         | 
   872         CX_TEST_ASSERT(*((int*)cxMapGet(dst, "k4")) == 10); | 
|         | 
   873     } | 
|         | 
   874     cxMapFree(dst); | 
|         | 
   875     cxMapFree(s1); | 
|         | 
   876     cxMapFree(s2); | 
|         | 
   877 } | 
|         | 
   878  | 
|         | 
   879 CX_TEST(test_hash_map_intersection_alloc_fail) { | 
|         | 
   880     CxMap *dst = cxHashMapCreateSimple(sizeof(int)); | 
|         | 
   881  | 
|         | 
   882     CxMap *s1 = cxHashMapCreateSimple(CX_STORE_POINTERS); | 
|         | 
   883     CxMap *s2 = cxHashMapCreateSimple(CX_STORE_POINTERS); | 
|         | 
   884     const char *s1_keys[] = {"k1", "k2", "k3", "k4"}; | 
|         | 
   885     int s1_values[] = {1, 3, 4, 6}; | 
|         | 
   886     const char *s2_keys[] = {"k4", "k5", "k2", "k6"}; | 
|         | 
   887     int s2_values[] = {5, 9, 15, 23}; | 
|         | 
   888     for (unsigned int i = 0 ; i < 4 ; i++) { | 
|         | 
   889         cxMapPut(s1, s1_keys[i], &s1_values[i]); | 
|         | 
   890         cxMapPut(s2, s2_keys[i], &s2_values[i]); | 
|         | 
   891     } | 
|         | 
   892     CX_TEST_DO { | 
|         | 
   893         int c = 4; | 
|         | 
   894         test_hash_map_clone_func_max_enabled = true; | 
|         | 
   895         test_hash_map_clone_func_max_clones = 1; | 
|         | 
   896         CX_TEST_ASSERT(0 != cxMapIntersection(dst, s1, s2, test_hash_map_clone_func, NULL, &c)); | 
|         | 
   897         test_hash_map_clone_func_max_enabled = false; | 
|         | 
   898         CX_TEST_ASSERT(cxMapSize(dst) == 1); | 
|         | 
   899         // the concrete element which is affected might change when the hash function changes | 
|         | 
   900         CX_TEST_ASSERT(*((int*)cxMapGet(dst, "k2")) == 7); | 
|         | 
   901         CX_TEST_ASSERT(cxMapGet(dst, "k4") == NULL); | 
|         | 
   902     } | 
|         | 
   903     cxMapFree(dst); | 
|         | 
   904     cxMapFree(s1); | 
|         | 
   905     cxMapFree(s2); | 
|         | 
   906 } | 
|         | 
   907  | 
|         | 
   908 CX_TEST(test_hash_map_list_intersection) { | 
|         | 
   909     CxMap *dst = cxHashMapCreateSimple(sizeof(int)); | 
|         | 
   910     CxMap *src = cxHashMapCreateSimple(sizeof(int)); | 
|         | 
   911     CxList *keys = cxArrayListCreate(NULL, cx_hash_key_cmp, sizeof(CxHashKey), 4); | 
|         | 
   912  | 
|         | 
   913     const char *src_keys[] = {"k1", "k2", "k3", "k4"}; | 
|         | 
   914     int src_values[] = {1, 3, 4, 6}; | 
|         | 
   915     for (unsigned int i = 0 ; i < 4 ; i++) { | 
|         | 
   916         cxMapPut(src, src_keys[i], &src_values[i]); | 
|         | 
   917     } | 
|         | 
   918     const char *k[] = {"k4", "k5", "k2", "k6"}; | 
|         | 
   919     for (unsigned int i = 0 ; i < 4 ; i++) { | 
|         | 
   920         CxHashKey key = CX_HASH_KEY(k[i]); | 
|         | 
   921         cxListAdd(keys, &key); | 
|         | 
   922     } | 
|         | 
   923     CX_TEST_DO { | 
|         | 
   924         int c = 4; | 
|         | 
   925         CX_TEST_ASSERT(0 == cxMapListIntersection(dst, src, keys, test_hash_map_clone_func, NULL, &c)); | 
|         | 
   926         CX_TEST_ASSERT(cxMapSize(dst) == 2); | 
|         | 
   927         CX_TEST_ASSERT(*((int*)cxMapGet(dst, "k2")) == 7); | 
|         | 
   928         CX_TEST_ASSERT(*((int*)cxMapGet(dst, "k4")) == 10); | 
|         | 
   929     } | 
|         | 
   930     cxMapFree(dst); | 
|         | 
   931     cxMapFree(src); | 
|         | 
   932     cxListFree(keys); | 
|         | 
   933 } | 
|         | 
   934  | 
|         | 
   935 CX_TEST(test_hash_map_list_intersection_alloc_fail) { | 
|         | 
   936     CxMap *dst = cxHashMapCreateSimple(sizeof(int)); | 
|         | 
   937     CxMap *src = cxHashMapCreateSimple(sizeof(int)); | 
|         | 
   938     CxList *keys = cxArrayListCreate(NULL, cx_hash_key_cmp, sizeof(CxHashKey), 4); | 
|         | 
   939  | 
|         | 
   940     const char *src_keys[] = {"k1", "k2", "k3", "k4"}; | 
|         | 
   941     int src_values[] = {1, 3, 4, 6}; | 
|         | 
   942     for (unsigned int i = 0 ; i < 4 ; i++) { | 
|         | 
   943         cxMapPut(src, src_keys[i], &src_values[i]); | 
|         | 
   944     } | 
|         | 
   945     const char *k[] = {"k4", "k5", "k2", "k6"}; | 
|         | 
   946     for (unsigned int i = 0 ; i < 4 ; i++) { | 
|         | 
   947         CxHashKey key = CX_HASH_KEY(k[i]); | 
|         | 
   948         cxListAdd(keys, &key); | 
|         | 
   949     } | 
|         | 
   950     CX_TEST_DO { | 
|         | 
   951         int c = 4; | 
|         | 
   952         test_hash_map_clone_func_max_enabled = true; | 
|         | 
   953         test_hash_map_clone_func_max_clones = 1; | 
|         | 
   954         CX_TEST_ASSERT(0 != cxMapListIntersection(dst, src, keys, test_hash_map_clone_func, NULL, &c)); | 
|         | 
   955         test_hash_map_clone_func_max_enabled = false; | 
|         | 
   956         CX_TEST_ASSERT(cxMapSize(dst) == 1); | 
|         | 
   957         // the concrete element which is affected might change when the hash function changes | 
|         | 
   958         CX_TEST_ASSERT(*((int*)cxMapGet(dst, "k2")) == 7); | 
|         | 
   959         CX_TEST_ASSERT(cxMapGet(dst, "k4") == NULL); | 
|         | 
   960     } | 
|         | 
   961     cxMapFree(dst); | 
|         | 
   962     cxMapFree(src); | 
|         | 
   963     cxListFree(keys); | 
|         | 
   964 } | 
|         | 
   965  | 
|         | 
   966 CX_TEST(test_hash_map_intersection_non_empty_target) { | 
|         | 
   967     CxMap *dst = cxHashMapCreateSimple(CX_STORE_POINTERS); | 
|         | 
   968     cxDefineAdvancedDestructor(dst, cxFree, (void*) cxDefaultAllocator); | 
|         | 
   969  | 
|         | 
   970     CxMap *s1 = cxHashMapCreateSimple(sizeof(int)); | 
|         | 
   971     CxMap *s2 = cxHashMapCreateSimple(sizeof(int)); | 
|         | 
   972     const char *s1_keys[] = {"k1", "k2", "k3", "k4"}; | 
|         | 
   973     int s1_values[] = {1, 3, 4, 6}; | 
|         | 
   974     const char *s2_keys[] = {"k4", "k5", "k2", "k6"}; | 
|         | 
   975     int s2_values[] = {5, 9, 15, 23}; | 
|         | 
   976     for (unsigned int i = 0 ; i < 4 ; i++) { | 
|         | 
   977         cxMapPut(s1, s1_keys[i], &s1_values[i]); | 
|         | 
   978         cxMapPut(s2, s2_keys[i], &s2_values[i]); | 
|         | 
   979     } | 
|         | 
   980  | 
|         | 
   981     // add k7 to dst which is not in src, and also not in the difference | 
|         | 
   982     int *k7 = cxMallocDefault(sizeof(int)); | 
|         | 
   983     *k7 = 1337; | 
|         | 
   984     cxMapPut(dst, "k7", k7); | 
|         | 
   985  | 
|         | 
   986     CX_TEST_DO { | 
|         | 
   987         int c = 4; | 
|         | 
   988         CX_TEST_ASSERT(0 == cxMapIntersection(dst, s1, s2, test_hash_map_clone_func, NULL, &c)); | 
|         | 
   989         CX_TEST_ASSERT(cxMapSize(dst) == 3); | 
|         | 
   990         CX_TEST_ASSERT(*((int*)cxMapGet(dst, "k2")) == 7); | 
|         | 
   991         CX_TEST_ASSERT(*((int*)cxMapGet(dst, "k4")) == 10); | 
|         | 
   992         CX_TEST_ASSERT(*(int*)cxMapGet(dst, "k7") == 1337); | 
|         | 
   993     } | 
|         | 
   994     cxMapFree(dst); | 
|         | 
   995     cxMapFree(s1); | 
|         | 
   996     cxMapFree(s2); | 
|         | 
   997 } | 
|         | 
   998  | 
|         | 
   999 CX_TEST(test_hash_map_list_intersection_non_empty_target) { | 
|         | 
  1000     CxMap *dst = cxHashMapCreateSimple(CX_STORE_POINTERS); | 
|         | 
  1001     cxDefineAdvancedDestructor(dst, cxFree, (void*) cxDefaultAllocator); | 
|         | 
  1002     CxMap *src = cxHashMapCreateSimple(sizeof(int)); | 
|         | 
  1003     CxList *keys = cxArrayListCreate(NULL, cx_hash_key_cmp, sizeof(CxHashKey), 4); | 
|         | 
  1004  | 
|         | 
  1005     const char *src_keys[] = {"k1", "k2", "k3", "k4"}; | 
|         | 
  1006     int src_values[] = {1, 3, 4, 6}; | 
|         | 
  1007     for (unsigned int i = 0 ; i < 4 ; i++) { | 
|         | 
  1008         cxMapPut(src, src_keys[i], &src_values[i]); | 
|         | 
  1009     } | 
|         | 
  1010     const char *k[] = {"k4", "k5", "k2", "k6"}; | 
|         | 
  1011     for (unsigned int i = 0 ; i < 4 ; i++) { | 
|         | 
  1012         CxHashKey key = CX_HASH_KEY(k[i]); | 
|         | 
  1013         cxListAdd(keys, &key); | 
|         | 
  1014     } | 
|         | 
  1015  | 
|         | 
  1016     // add k7 to dst which is not in src, and also not in the difference | 
|         | 
  1017     int *k7 = cxMallocDefault(sizeof(int)); | 
|         | 
  1018     *k7 = 1337; | 
|         | 
  1019     cxMapPut(dst, "k7", k7); | 
|         | 
  1020  | 
|         | 
  1021     CX_TEST_DO { | 
|         | 
  1022         int c = 4; | 
|         | 
  1023         CX_TEST_ASSERT(0 == cxMapListIntersection(dst, src, keys, test_hash_map_clone_func, NULL, &c)); | 
|         | 
  1024         CX_TEST_ASSERT(cxMapSize(dst) == 3); | 
|         | 
  1025         CX_TEST_ASSERT(*((int*)cxMapGet(dst, "k2")) == 7); | 
|         | 
  1026         CX_TEST_ASSERT(*((int*)cxMapGet(dst, "k4")) == 10); | 
|         | 
  1027         CX_TEST_ASSERT(*(int*)cxMapGet(dst, "k7") == 1337); | 
|         | 
  1028     } | 
|         | 
  1029  | 
|         | 
  1030     cxMapFree(dst); | 
|         | 
  1031     cxMapFree(src); | 
|         | 
  1032     cxListFree(keys); | 
|         | 
  1033 } | 
|         | 
  1034  | 
|         | 
  1035 CX_TEST(test_hash_map_intersection_ptr) { | 
|         | 
  1036     CxTestingAllocator talloc; | 
|         | 
  1037     cx_testing_allocator_init(&talloc); | 
|         | 
  1038     CxAllocator *allocator = &talloc.base; | 
|         | 
  1039     CxMap *dst = cxHashMapCreateSimple(CX_STORE_POINTERS); | 
|         | 
  1040     cxDefineAdvancedDestructor(dst, cxFree, allocator); | 
|         | 
  1041  | 
|         | 
  1042     CxMap *s1 = cxHashMapCreateSimple(CX_STORE_POINTERS); | 
|         | 
  1043     CxMap *s2 = cxHashMapCreateSimple(CX_STORE_POINTERS); | 
|         | 
  1044     const char *s1_keys[] = {"k1", "k2", "k3", "k4"}; | 
|         | 
  1045     int s1_values[] = {1, 3, 4, 6}; | 
|         | 
  1046     const char *s2_keys[] = {"k4", "k5", "k2", "k6"}; | 
|         | 
  1047     int s2_values[] = {5, 9, 15, 23}; | 
|         | 
  1048     for (unsigned int i = 0 ; i < 4 ; i++) { | 
|         | 
  1049         cxMapPut(s1, s1_keys[i], &s1_values[i]); | 
|         | 
  1050         cxMapPut(s2, s2_keys[i], &s2_values[i]); | 
|         | 
  1051     } | 
|         | 
  1052     CX_TEST_DO { | 
|         | 
  1053         int c = 4; | 
|         | 
  1054         CX_TEST_ASSERT(0 == cxMapIntersection(dst, s1, s2, test_hash_map_clone_func, allocator, &c)); | 
|         | 
  1055         CX_TEST_ASSERT(cxMapSize(dst) == 2); | 
|         | 
  1056         CX_TEST_ASSERT(*((int*)cxMapGet(dst, "k2")) == 7); | 
|         | 
  1057         CX_TEST_ASSERT(*((int*)cxMapGet(dst, "k4")) == 10); | 
|         | 
  1058         CX_TEST_ASSERT(cx_testing_allocator_used(&talloc)); | 
|    848     } | 
  1059     } | 
|    849     cxMapFree(dst); | 
  1060     cxMapFree(dst); | 
|    850     cxMapFree(s1); | 
  1061     cxMapFree(s1); | 
|    851     cxMapFree(s2); | 
  1062     cxMapFree(s2); | 
|    852     cx_testing_allocator_destroy(&talloc); | 
  1063     cx_testing_allocator_destroy(&talloc); |