diff --git a/src/l1_5/anne/l1_5_templ_very_base.h b/src/l1_5/anne/l1_5_templ_very_base.h index 798b527..479b283 100644 --- a/src/l1_5/anne/l1_5_templ_very_base.h +++ b/src/l1_5/anne/l1_5_templ_very_base.h @@ -7,8 +7,7 @@ void generate_l1_5_template_instantiation_for_base_types(){ SpanU8 l = cstr("l1_5"); SpanU8 ns = cstr(""); SpanU8 dep = cstr( - "#include \"../l1/VecAndSpan_int_primitives.h\"\n" - "#include \"../l1/Option_int_primitives.h\"" + "#include \"../l1/VecAndSpan_int_primitives.h\"" ); // todo: split VecAndSpan_int_primitives into multiple files (one file per integer type) generate_rb_tree_Set_templ_inst_guarded_header(l, ns, dep, (set_instantiation_op){.T = cstr("U64"), .t_integer = true}); diff --git a/src/l1_5/codegen/rb_tree_set_map_template_inst.h b/src/l1_5/codegen/rb_tree_set_map_template_inst.h index 496e4b9..561e19e 100644 --- a/src/l1_5/codegen/rb_tree_set_map_template_inst.h +++ b/src/l1_5/codegen/rb_tree_set_map_template_inst.h @@ -149,10 +149,61 @@ void codegen_append_rb_tree_set_insert_kind_method( } void codegen_append_rb_tree_set_erase_kind_method( - VecU8* result, set_instantiation_op op, SpanU8 set, SpanU8 method_name, - VecU8 Fc, VecU8 Tc_z_available, VecU8 Tc_returning + VecU8* result, set_instantiation_op op, SpanU8 set, SpanU8 method_name, VecU8 RT, + VecU8 Fc, VecU8 Tc_cur_available, VecU8 Tc_returning ){ - // todo: move deletion here + VecU8 not_found_case = prepend_spaces_to_SpanU8_lines(VecU8_to_span(&Fc), 3); + VecU8 saving_prev = prepend_spaces_to_SpanU8_lines(VecU8_to_span(&Tc_cur_available), 1); + VecU8 ret_found_case = prepend_spaces_to_SpanU8_lines(VecU8_to_span(&Tc_returning), 1); + VecU8_drop(Fc); + VecU8_drop(Tc_cur_available); + VecU8_drop(Tc_returning); + + VecU8_append_vec(result, VecU8_fmt( + "%v %s_%s(%s* self, %v key) {\n" /* RT, set, method_name, set, taking_ref_t_argument */ + SPACE "U64 cur = self->root;\n" + SPACE "while (true){\n" + SPACE SPACE "if (cur == 0) {\n" + "%v" /* not_found_case */ + SPACE SPACE "}\n" + SPACE SPACE "if (%v)\n" /* key_ref_EQUAL_element */ + SPACE SPACE SPACE "break;\n" + SPACE SPACE "if (%v)\n" /* key_ref_LESS_element */ + SPACE SPACE SPACE "cur = self->tree.buf[cur].left;\n" + SPACE SPACE "else\n" + SPACE SPACE SPACE "cur = self->tree.buf[cur].right;\n" + SPACE "}\n" + "%v" /* saving_prev */ + SPACE "U64 z = cur;\n" + SPACE "U64 y = (self->tree.buf[z].left == 0 || self->tree.buf[z].right == 0) ? z : RBTree_minimum_in_subtree(self->tree.buf, self->tree.buf[z].right);\n" + SPACE "U64 x = self->tree.buf[y].left != 0 ? self->tree.buf[y].left : self->tree.buf[y].right;\n" + SPACE "U64 py = self->tree.buf[y].parent;\n" // May be null + SPACE "self->tree.buf[x].parent = self->tree.buf[y].parent;\n" + SPACE "if (py == 0)\n" + SPACE SPACE "self->root = x;\n" + SPACE "else if (self->tree.buf[py].left == y)\n" + SPACE SPACE "self->tree.buf[py].left = x;\n" + SPACE "else\n" + SPACE SPACE "self->tree.buf[py].right = x;\n" + SPACE "RBTreeColor y_org_clr = self->tree.buf[y].color;\n" + SPACE "if (z != y)\n" + SPACE SPACE "RBTree_steal_neighbours(self->tree.buf, &self->root, z, y);\n" + SPACE "U64 L = self->el.len;\n" /* self->tree.len - 1 */ + SPACE "RBTree_steal_neighbours(self->tree.buf, &self->root, L, z);\n" + SPACE "self->tree.len--;\n" + SPACE "self->el.buf[z-1] = self->el.buf[L-1];\n" + SPACE "self->el.len--;\n" + SPACE "if (y_org_clr)\n" + SPACE SPACE "RBTree_fix_after_delete(self->tree.buf, &self->root, x);\n" + "%v" /* ret_found_case */ + "}\n\n", + RT, set, method_name, set, codegen_rb_tree_set_taking_ref_t_argument(op), + not_found_case, + codegen_rb_tree_set_key_ref_EQUAL_element(op), + codegen_rb_tree_set_key_ref_LESS_element(op), + saving_prev, + ret_found_case + )); } /* src/l1_5/core/rb_tree_node.h is a dependency of all instantiations of rb_tree_set template @@ -217,46 +268,19 @@ NODISCARD VecU8 generate_rb_tree_Set_template_instantiation(set_instantiation_op op.T, codegen_rb_tree_set_some_t(op, cstr("old")))); } - VecU8_append_vec(&res, VecU8_fmt( - "bool %s_erase(%s* self, %v key) {\n" /* set, codegen_rb_tree_set_taking_ref_t_argument */ - SPACE "U64 cur = self->root;\n" - SPACE "while (true){\n" - SPACE SPACE "if (cur == 0)\n" - SPACE SPACE SPACE "return false;\n" - SPACE SPACE "if (%v)\n" - SPACE SPACE SPACE "break;\n" - SPACE SPACE "if (%v)\n" - SPACE SPACE SPACE "cur = self->tree.buf[cur].left;\n" - SPACE SPACE "else\n" - SPACE SPACE SPACE "cur = self->tree.buf[cur].right;\n" - SPACE "}\n" - SPACE "U64 z = cur;\n" - SPACE "U64 y = (self->tree.buf[z].left == 0 || self->tree.buf[z].right == 0) ? z : RBTree_minimum_in_subtree(self->tree.buf, self->tree.buf[z].right);\n" - SPACE "U64 x = self->tree.buf[y].left != 0 ? self->tree.buf[y].left : self->tree.buf[y].right;\n" - SPACE "U64 py = self->tree.buf[y].parent;\n" // May be null - SPACE "self->tree.buf[x].parent = self->tree.buf[y].parent;\n" - SPACE "if (py == 0)\n" - SPACE SPACE "self->root = x;\n" - SPACE "else if (self->tree.buf[py].left == y)\n" - SPACE SPACE "self->tree.buf[py].left = x;\n" - SPACE "else\n" - SPACE SPACE "self->tree.buf[py].right = x;\n" - SPACE "RBTreeColor y_org_clr = self->tree.buf[y].color;\n" - SPACE "if (z != y)\n" - SPACE SPACE "RBTree_steal_neighbours(self->tree.buf, &self->root, z, y);\n" - SPACE "U64 L = self->el.len;\n" /* self->tree.len - 1 */ - SPACE "RBTree_steal_neighbours(self->tree.buf, &self->root, L, z);\n" - SPACE "self->tree.len--;\n" - SPACE "self->el.buf[z-1] = self->el.buf[L-1];\n" - SPACE "self->el.len--;\n" - SPACE "if (y_org_clr)\n" - SPACE SPACE "RBTree_fix_after_delete(self->tree.buf, &self->root, x);\n" - SPACE "return true;\n" - "}\n\n", - set, set, codegen_rb_tree_set_taking_ref_t_argument(op), - codegen_rb_tree_set_key_ref_EQUAL_element(op), - codegen_rb_tree_set_key_ref_LESS_element(op) - )); + codegen_append_rb_tree_set_erase_kind_method(&res, op, set, cstr("erase"), vcstr("bool"), + vcstr("return false;\n"), + op.t_primitive ? vcstr("") : VecU8_fmt("%s_drop(self->el.buf[cur - 1]);\n", op.T), + vcstr("return true;\n")); + + if (!op.t_integer) { + codegen_append_rb_tree_set_erase_kind_method(&res, op, set, cstr("pop"), + codegen_rb_tree_set_option_returned_value_t(op), + VecU8_fmt("return %v;\n", codegen_rb_tree_set_none_t(op)), + VecU8_fmt("%s saved = self->el[cur - 1];\n", op.T), + VecU8_fmt("return %v;\n", codegen_rb_tree_set_some_t(op, cstr("saved"))) + ); + } VecU8_append_vec(&res, VecU8_fmt( "U64 %s_find(const %s* self, %v key) {\n" /* set, set taking_ref_t_argument */