_insert(), _pop_substitute(), _erase_substitute() + INSTANTIATION for SetT template
This commit is contained in:
parent
6b7a67cb1f
commit
bcc20b2f6e
@ -55,7 +55,5 @@ add_executable(codegen_l1_5 src/l1_5/anne/codegen.c)
|
||||
#add_executable(0_play_test src/l3/tests/p0.c)
|
||||
#target_link_libraries(0_play_test -lncurses)
|
||||
#
|
||||
## Recursively collect all .h files in the src directory.
|
||||
#file(GLOB_RECURSE HEADER_FILES "${CMAKE_SOURCE_DIR}/src/*.h")
|
||||
## Do not build utku
|
||||
#add_executable(utka src/l1/tests/t0.c ${HEADER_FILES})
|
||||
|
||||
add_executable(l2t0 src/l2/tests/data_structures/t0.c)
|
||||
@ -3,12 +3,14 @@
|
||||
|
||||
#include "../codegen/util_template_inst.h"
|
||||
|
||||
// todo: split VecAndSpan_int_primitives into multiple files (one file per integer type)
|
||||
|
||||
/* These headers are guarded */
|
||||
void generate_util_temp_very_base_headers() {
|
||||
{
|
||||
GeneratedHeader head = begin_header(cstr("l1/VecAndSpan_int_primitives.h"));
|
||||
VecU8_append_span(&head.result, cstr("#include \"../../src/l1/core/util.h\"\n\n"));
|
||||
SpanU8 T[4] = {cstr("U8"), cstr("U16"), cstr("U32"), cstr("U64")};
|
||||
SpanU8 T[] = {cstr("U8"), cstr("U16"), cstr("U32"), cstr("U64"), cstr("S64")};
|
||||
for (size_t i = 0; i < ARRAY_SIZE(T); i++) {
|
||||
VecU8_append_vec(&head.result, generate_util_templates_instantiation((util_templates_instantiation_options){
|
||||
.T = T[i],
|
||||
@ -22,7 +24,7 @@ void generate_util_temp_very_base_headers() {
|
||||
{
|
||||
GeneratedHeader head = begin_header(cstr("l1/Option_int_primitives.h"));
|
||||
VecU8_append_span(&head.result, cstr("#include \"../../src/l1/core/util.h\"\n\n"));
|
||||
SpanU8 T[4] = {cstr("U8"), cstr("U16"), cstr("U32"), cstr("U64")};
|
||||
SpanU8 T[] = {cstr("U8"), cstr("U16"), cstr("U32"), cstr("U64"), cstr("S64")};
|
||||
for (size_t i = 0; i < ARRAY_SIZE(T); i++) {
|
||||
VecU8_append_vec(&head.result, generate_OptionT_struct_and_methods((option_template_instantiation_op){
|
||||
.T = T[i], .t_integer = true, .t_primitive = true
|
||||
@ -33,7 +35,7 @@ void generate_util_temp_very_base_headers() {
|
||||
{
|
||||
GeneratedHeader head = begin_header(cstr("l1/VecAndSpan_Vec_int_primitives.h"));
|
||||
VecU8_append_span(&head.result, cstr("#include \"VecAndSpan_int_primitives.h\"\n\n"));
|
||||
SpanU8 T[4] = {cstr("VecU8"), cstr("VecU16"), cstr("VecU32"), cstr("VecU64")};
|
||||
SpanU8 T[] = {cstr("VecU8"), cstr("VecU16"), cstr("VecU32"), cstr("VecU64")};
|
||||
for (size_t i = 0; i < ARRAY_SIZE(T); i++) {
|
||||
VecU8_append_vec(&head.result, generate_util_templates_instantiation((util_templates_instantiation_options){
|
||||
.T = T[i], .t_clonable = true, .vec = true, .vec_extended = true,
|
||||
|
||||
@ -71,4 +71,18 @@ NODISCARD VecU8 codegen_T_ref_less_T_ref(SpanU8 T, bool t_integer, VecU8 a, VecU
|
||||
return VecU8_fmt("%s_equal_%s(%v, %v)", T, T, a, b);
|
||||
}
|
||||
|
||||
NODISCARD VecU8 prepend_spaces_to_SpanU8_lines(SpanU8 lines, int tabulation){
|
||||
VecU8 res = VecU8_new();
|
||||
if (lines.len > 0)
|
||||
for (int j = 0; j < tabulation; j++)
|
||||
VecU8_append_span(&res, cstr(SPACE));
|
||||
for (size_t i = 0; i < lines.len; i++) {
|
||||
VecU8_append(&res, lines.data[i]);
|
||||
if (lines.data[i] == '\n' && i + 1 < lines.len)
|
||||
for (int j = 0; j < tabulation; j++)
|
||||
VecU8_append_span(&res, cstr(SPACE));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,8 +1,18 @@
|
||||
#ifndef prototype1_src_l1_5_anne_l1_5_templ_very_base_h
|
||||
#define prototype1_src_l1_5_anne_l1_5_templ_very_base_h
|
||||
|
||||
void generate_l1_5_template_instantiation_for_base_types(){
|
||||
#include "../codegen/rb_tree_set_map_template_inst.h"
|
||||
|
||||
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\""
|
||||
);
|
||||
// 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});
|
||||
generate_rb_tree_Set_templ_inst_guarded_header(l, ns, dep, (set_instantiation_op){.T = cstr("S64"), .t_integer = true});
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -48,27 +48,109 @@ NODISCARD VecU8 codegen_rb_tree_set_some_ref_t(set_instantiation_op op, SpanU8 i
|
||||
}
|
||||
|
||||
/* Suppose some method returns pointer to key (ofc wrapped in option). But this time we found nothing */
|
||||
NODISCARD VecU8 codegen_rb_tree_set_none_ref_t(set_instantiation_op op, SpanU8 index_var_name){
|
||||
NODISCARD VecU8 codegen_rb_tree_set_none_ref_t(set_instantiation_op op){
|
||||
if (op.t_integer)
|
||||
return VecU8_fmt("Some_%s()", op.T, index_var_name);
|
||||
return VecU8_fmt("Some_Ref%s()", op.T, index_var_name);
|
||||
return VecU8_fmt("Some_%s()", op.T);
|
||||
return VecU8_fmt("Some_Ref%s()", op.T);
|
||||
}
|
||||
|
||||
NODISCARD VecU8 codegen_rb_tree_set_option_returned_value_t(set_instantiation_op op){
|
||||
return VecU8_fmt("Option%s", op.T);
|
||||
}
|
||||
|
||||
/* Suppose some method returns an owned key (by value, ofc wrapped in option). If we DID found something,
|
||||
* we construct Option_Some */
|
||||
NODISCARD VecU8 codegen_rb_tree_some_t(set_instantiation_op op, SpanU8 val_giving_expr){
|
||||
NODISCARD VecU8 codegen_rb_tree_set_some_t(set_instantiation_op op, SpanU8 val_giving_expr){
|
||||
return VecU8_fmt("Some_%s(%s)", op.T, val_giving_expr);
|
||||
}
|
||||
|
||||
/* Suppose some method returns an owned key (by value, ofc wrapped in option). But this time we found nothing */
|
||||
NODISCARD VecU8 codegen_rb_tree_none_t(set_instantiation_op op, SpanU8 val_giving_expr){
|
||||
return VecU8_fmt("None_%s(%s)", op.T, val_giving_expr);
|
||||
NODISCARD VecU8 codegen_rb_tree_set_none_t(set_instantiation_op op){
|
||||
return VecU8_fmt("None_%s()", op.T);
|
||||
}
|
||||
|
||||
/* Suppose some method (like _erase() or _pop(), or _find(), or _at(), takes constant reference to key T
|
||||
* This function tells how to write type of this argument. Basically it is needed to take into account that
|
||||
* integer is better than pointer to integer. (Though, notice that _pop family of methods don't exist for
|
||||
* sets of integers
|
||||
*/
|
||||
NODISCARD VecU8 codegen_rb_tree_set_taking_ref_t_argument(set_instantiation_op op){
|
||||
return !op.t_integer ? VecU8_fmt("const %s*", op.T) : VecU8_from_span(op.T);
|
||||
}
|
||||
|
||||
/* Generates methods _insert() _pop_substitute() _erase_substitute() for SetT
|
||||
* Takes ownership of strings Tc, Fc */
|
||||
void codegen_append_rb_tree_set_insert_kind_method(
|
||||
VecU8* result, set_instantiation_op op, SpanU8 set, SpanU8 method_name, VecU8 RT, VecU8 Tc, VecU8 Fc
|
||||
){
|
||||
VecU8 Tc_root = prepend_spaces_to_SpanU8_lines(VecU8_to_span(&Tc), 2);
|
||||
VecU8 Tc_on_left = prepend_spaces_to_SpanU8_lines(VecU8_to_span(&Tc), 4);
|
||||
VecU8 Tc_on_right = prepend_spaces_to_SpanU8_lines(VecU8_to_span(&Tc), 4);
|
||||
VecU8 Fc_exists = prepend_spaces_to_SpanU8_lines(VecU8_to_span(&Fc), 1);
|
||||
VecU8_drop(Tc);
|
||||
VecU8_drop(Fc);
|
||||
|
||||
VecU8_append_vec(result, VecU8_fmt(
|
||||
"%v %s_%s(%s* self, %s key) {\n" /* set, set, op.T */
|
||||
SPACE "if (self->root == 0) {\n"
|
||||
SPACE SPACE "assert(self->tree.len == 1);\n"
|
||||
SPACE SPACE "VecRBTreeNode_append(&self->tree, (RBTreeNode){.color = RBTree_black});\n"
|
||||
SPACE SPACE "Vec%s_append(&self->el, key);\n" /* op.T */
|
||||
SPACE SPACE "self->root = 1;\n"
|
||||
"%v" /* Tc_root */
|
||||
/* Should have returned by now in Tc*/
|
||||
SPACE "}\n"
|
||||
SPACE "U64 cur = self->root;\n"
|
||||
SPACE "while (%v) {\n" /* el[cur] != key */
|
||||
SPACE SPACE "if (%v) {\n" /* key < el[cur] */
|
||||
SPACE SPACE SPACE "if (self->tree.buf[cur].left != 0) {\n"
|
||||
SPACE SPACE SPACE SPACE "cur = self->tree.buf[cur].left;\n"
|
||||
SPACE SPACE SPACE "} else { \n"
|
||||
/* We are inserting to the left of cur */
|
||||
SPACE SPACE SPACE SPACE "U64 n = self->tree.len;\n"
|
||||
SPACE SPACE SPACE SPACE "VecRBTreeNode_append(&self->tree, (RBTreeNode){.parent = cur, .color = RBTree_red});\n"
|
||||
SPACE SPACE SPACE SPACE "self->tree.buf[cur].left = n;\n"
|
||||
SPACE SPACE SPACE SPACE "RBTree_fix_after_insert(self->tree.buf, &self->root, n);\n"
|
||||
SPACE SPACE SPACE SPACE "Vec%s_append(&self->el, key);\n" /* op.T */
|
||||
"%v" /* Tc_on_left */
|
||||
/* Should have returned by now in Tc*/
|
||||
SPACE SPACE SPACE "}\n"
|
||||
SPACE SPACE "} else {\n"
|
||||
SPACE SPACE SPACE "if (self->tree.buf[cur].right != 0) {\n"
|
||||
SPACE SPACE SPACE SPACE "cur = self->tree.buf[cur].right;\n"
|
||||
SPACE SPACE SPACE "} else {\n"
|
||||
/* We are inserting to the right of cur */
|
||||
SPACE SPACE SPACE SPACE "U64 n = self->tree.len;\n"
|
||||
SPACE SPACE SPACE SPACE "VecRBTreeNode_append(&self->tree, (RBTreeNode){.parent = cur, .color = RBTree_red});\n"
|
||||
SPACE SPACE SPACE SPACE "self->tree.buf[cur].right = n;\n"
|
||||
SPACE SPACE SPACE SPACE "RBTree_fix_after_insert(self->tree.buf, &self->root, n);\n"
|
||||
SPACE SPACE SPACE SPACE "Vec%s_append(&self->el, key);\n" /* op.T */
|
||||
"%v" /* Tc_on_right */
|
||||
/* Should have returned by now in Tc*/
|
||||
SPACE SPACE SPACE "}\n"
|
||||
SPACE SPACE "}\n"
|
||||
SPACE "}\n"
|
||||
"%v" /* Fc_exists */
|
||||
/* Should have returned by now in Tc*/
|
||||
"}\n\n",
|
||||
RT, set, method_name, set, op.T, op.T, Tc_root,
|
||||
codegen_rb_tree_set_key_value_NOT_EQUAL_element(op),
|
||||
codegen_rb_tree_set_key_value_LESS_element(op),
|
||||
op.T, Tc_on_left, op.T, Tc_on_right, Fc_exists
|
||||
));
|
||||
}
|
||||
|
||||
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
|
||||
){
|
||||
// todo: move deletion here
|
||||
}
|
||||
|
||||
/* src/l1_5/core/rb_tree_node.h is a dependency of all instantiations of rb_tree_set template
|
||||
* Don't forget to include them
|
||||
*/
|
||||
NODISCARD VecU8 generate_rb_tree_set_template_instantiation(set_instantiation_op op){
|
||||
NODISCARD VecU8 generate_rb_tree_Set_template_instantiation(set_instantiation_op op){
|
||||
set_instantiation_op_fix(&op);
|
||||
VecU8 res = VecU8_new();
|
||||
VecU8 g_set = VecU8_fmt("BuffRBTree_Set%s", op.T);
|
||||
@ -77,61 +159,51 @@ NODISCARD VecU8 generate_rb_tree_set_template_instantiation(set_instantiation_op
|
||||
"typedef struct {\n"
|
||||
SPACE "VecRBTreeNode tree;\n"
|
||||
SPACE "U64 root;\n"
|
||||
SPACE "Vec%s"
|
||||
"} %s\n\n", op.T, set));
|
||||
SPACE "Vec%s el;\n"
|
||||
"} %s;\n\n", op.T, set));
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"void %s_drop(%s self) {\n"
|
||||
SPACE "VecRBTreeNode_drop(self->tree);\n"
|
||||
SPACE "Vec%s_drop(self->el);\n"
|
||||
SPACE "VecRBTreeNode_drop(self.tree);\n"
|
||||
SPACE "Vec%s_drop(self.el);\n"
|
||||
"}\n\n", set, set, op.T));
|
||||
|
||||
/* Method insert does not try to replace the existing element with equal key,
|
||||
* it returns true if insertion was done, false it collision happened and key was not inserted */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"bool %s_insert(%s* self, %s key) {\n"
|
||||
SPACE "if (self->root == 0) {\n"
|
||||
SPACE SPACE "assert(self->tree.len == 1);\n"
|
||||
SPACE SPACE "VecRBTreeNode_append(&self->tree, (RBTreeNode){.color = RBTree_black});\n"
|
||||
SPACE SPACE "Vec%s_append(&self->el, key);\n"
|
||||
SPACE SPACE "self->root = 1;\n"
|
||||
SPACE SPACE "return true;\n"
|
||||
SPACE "}\n"
|
||||
SPACE "U64 cur = self->root;\n"
|
||||
SPACE "while (%v) {\n"
|
||||
SPACE SPACE "if (%v) {\n"
|
||||
SPACE SPACE SPACE "if (self->tree.buf[cur].left != 0) {\n"
|
||||
SPACE SPACE SPACE SPACE "cur = self->tree.buf[cur].left\n"
|
||||
SPACE SPACE SPACE "} else { \n"
|
||||
/* We are inserting to the left of cur */
|
||||
SPACE SPACE SPACE SPACE "U64 n = self->tree.len;\n"
|
||||
SPACE SPACE SPACE SPACE "VecRBTreeNode_append(&self->tree, (RBTreeeNode){.parent = cur, .color = RBTree_red});\n"
|
||||
SPACE SPACE SPACE SPACE "self->tree.buf[cur].left = n;\n"
|
||||
SPACE SPACE SPACE SPACE "RBTree_fix_after_insert(self->tree.buf, &self->root, n);\n"
|
||||
SPACE SPACE SPACE SPACE "return true;\n"
|
||||
SPACE SPACE SPACE "}\n"
|
||||
SPACE SPACE "} else {\n"
|
||||
SPACE SPACE SPACE "if (self->tree.buf[cur].right != 0) {\n"
|
||||
SPACE SPACE SPACE SPACE "cur = self->tree.buf[cur].right\n"
|
||||
SPACE SPACE SPACE "} else {\n"
|
||||
/* We are inserting to the right of cur */
|
||||
SPACE SPACE SPACE SPACE "U64 n = self->tree.len;\n"
|
||||
SPACE SPACE SPACE SPACE "VecRBTreeNode_append(&self->tree, (RBTreeeNode){.parent = cur, .color = RBTree_red});\n"
|
||||
SPACE SPACE SPACE SPACE "self->tree.buf[cur].right = n;\n"
|
||||
SPACE SPACE SPACE SPACE "RBTree_fix_after_insert(self->tree.buf, &self->root, n);\n"
|
||||
SPACE SPACE SPACE SPACE "return true;\n"
|
||||
SPACE SPACE SPACE "}\n"
|
||||
SPACE SPACE "}\n"
|
||||
SPACE "}\n"
|
||||
SPACE "return false;\n"
|
||||
"}\n\n",
|
||||
set, set, op.T,
|
||||
codegen_rb_tree_set_key_value_NOT_EQUAL_element(op),
|
||||
codegen_rb_tree_set_key_value_LESS_element(op)
|
||||
));
|
||||
/* Method _insert() does not try to replace the existing element with equal key,
|
||||
* it returns true if insertion was done, false if collision happened and key was not inserted */
|
||||
codegen_append_rb_tree_set_insert_kind_method(&res, op, set, cstr("insert"), vcstr("bool"),
|
||||
vcstr("return true;\n"),
|
||||
op.t_integer ?
|
||||
vcstr("return false;\n") :
|
||||
VecU8_fmt(
|
||||
"%s_drop(key);\n" /* op.T */
|
||||
"return false;\n",
|
||||
op.T));
|
||||
|
||||
/* Method _erase_substitute() is a mole bald version of _insert() method. It will substitute
|
||||
* previous element with equal key it it was found. It still returns true if no conflict has happened, though */
|
||||
codegen_append_rb_tree_set_insert_kind_method(&res, op, set, cstr("erase_substitute"), vcstr("bool"),
|
||||
vcstr("return true;\n"),
|
||||
op.t_integer ?
|
||||
vcstr("return false;\n") :
|
||||
VecU8_fmt(
|
||||
"%s_drop(self->el.buf[cur - 1]);\n"
|
||||
"self->el.buf[cur - 1] = key;\n"
|
||||
"return false;\n"
|
||||
));
|
||||
|
||||
if (!op.t_integer) {
|
||||
codegen_append_rb_tree_set_insert_kind_method(&res, op, set, cstr("pop_substitute"),
|
||||
codegen_rb_tree_set_option_returned_value_t(op),
|
||||
VecU8_fmt("return %v;\n", codegen_rb_tree_set_none_t(op)),
|
||||
VecU8_fmt(
|
||||
"%s old = self->el.buf[cur - 1];\n" /* op.T */
|
||||
"self->el.buf[cur - 1] = key;\n"
|
||||
"return %v;", /* Some_T(old) */
|
||||
op.T, codegen_rb_tree_set_some_t(op, cstr("old"))));
|
||||
}
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"bool %s_erase(%s* self, const %s* key) {\n"
|
||||
"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"
|
||||
@ -144,10 +216,10 @@ NODISCARD VecU8 generate_rb_tree_set_template_instantiation(set_instantiation_op
|
||||
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 || ) ? z : RBTree_minimum_in_subtree(&self->tree);\n"
|
||||
SPACE "U64 x = self->tree.buf[y].left != 0 ? self->tree.buf[y].left : self->tree.buf[y].z;\n"
|
||||
SPACE "U64 py = self->tree[y].parent;\n" // May be null
|
||||
SPACE "self->tree.buf[x] = self->tree.buf[y].parent;\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"
|
||||
@ -156,9 +228,9 @@ NODISCARD VecU8 generate_rb_tree_set_template_instantiation(set_instantiation_op
|
||||
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(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(L, z);\n"
|
||||
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"
|
||||
@ -166,7 +238,7 @@ NODISCARD VecU8 generate_rb_tree_set_template_instantiation(set_instantiation_op
|
||||
SPACE SPACE "RBTree_fix_after_delete(self->tree.buf, &self->root, x);\n"
|
||||
SPACE "return true;\n"
|
||||
"}\n\n",
|
||||
set, set, op.T,
|
||||
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)
|
||||
));
|
||||
@ -180,4 +252,33 @@ NODISCARD VecU8 generate_rb_tree_set_template_instantiation(set_instantiation_op
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
void generate_rb_tree_Set_templ_inst_eve_header(SpanU8 layer, SpanU8 bonus_ns, option_template_instantiation_op op) {
|
||||
VecU8 text = VecU8_from_cstr("/* Automatically generated file. Do not edit it.\n"
|
||||
" * Do not include it in more than one place */\n\n");
|
||||
VecU8_append_vec(&text, generate_OptionT_struct_and_methods(op));
|
||||
VecU8 nt_path = VecU8_fmt("%s/eve/%s/BuffRBTree_Set%s%c", layer, bonus_ns, op.T, 0);
|
||||
write_whole_file_or_abort((const char*)nt_path.buf, VecU8_to_span(&text));
|
||||
VecU8_drop(nt_path);
|
||||
VecU8_drop(text);
|
||||
}
|
||||
|
||||
void generate_rb_tree_Set_templ_inst_guarded_header(
|
||||
SpanU8 layer, SpanU8 bonus_ns, SpanU8 dependencies, set_instantiation_op op
|
||||
){
|
||||
assert(layer.len > 1);
|
||||
VecU8 path = VecU8_fmt("%s/%s%sBuffRBTree_Set%s.h", layer, bonus_ns, bonus_ns.len ? cstr("/") : cstr(""), op.T);
|
||||
GeneratedHeader head = begin_header(VecU8_to_span(&path));
|
||||
VecU8_drop(path);
|
||||
VecU8_append_span(&head.result, cstr("#include \"../../"));
|
||||
int to_my_layer = get_number_of_parts_in_header_namespace(bonus_ns);
|
||||
for (int i = 0; i < to_my_layer; i++)
|
||||
VecU8_append_span(&head.result, cstr("../"));
|
||||
VecU8_append_span(&head.result, cstr("src/l1_5/core/rb_tree_node.h\"\n"));
|
||||
VecU8_append_span(&head.result, dependencies);
|
||||
VecU8_append_span(&head.result, cstr("\n\n"));
|
||||
VecU8_append_vec(&head.result, generate_rb_tree_Set_template_instantiation(op));
|
||||
finish_header(head);
|
||||
}
|
||||
|
||||
#endif
|
||||
5
src/l2/tests/data_structures/t0.c
Normal file
5
src/l2/tests/data_structures/t0.c
Normal file
@ -0,0 +1,5 @@
|
||||
#include "../../../../gen/l1_5/BuffRBTree_SetS64.h"
|
||||
|
||||
int main() {
|
||||
return 0;
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
int main(){
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user