Removed all vibecoded code. Now Alice API is fully exposed to C++

This commit is contained in:
Андреев Григорий 2026-04-13 15:05:12 +03:00
parent 80d4a990c0
commit 0808250637
3 changed files with 250 additions and 510 deletions

View File

@ -1,533 +1,250 @@
#pragma once
#include <string>
#include <functional>
#include "../codegen.hpp"
#include <array>
#include <concepts>
#include <functional>
#include <string>
#include <string_view>
#include <utility>
/* This file is vibecoded. It requires more rewriting */
inline constexpr std::array<std::string_view, 4> kGeomFieldNames = {"x", "y", "z", "w"};
struct GeomVecFamilySpec {
std::string_view prefix;
std::string_view scalar;
bool geometric_methods;
template <class F>
concept CallableMatCordToStr = requires(F&& f) {
{std::invoke(std::forward<F>(f), int{}, int{})} -> std::convertible_to<std::string>;
};
struct GeomMatFamilySpec {
std::string_view mat_prefix;
std::string_view vec_prefix;
std::string_view scalar;
};
template <class F>
concept GeomIndexCallable =
requires(F&& f) {
std::invoke(std::forward<F>(f), int{});
};
template <class F>
concept GeomIndexStringCallable =
requires(F&& f) {
{ std::invoke(std::forward<F>(f), int{}) } -> std::convertible_to<std::string>;
};
template <class F>
concept GeomIndexPairStringCallable =
requires(F&& f) {
{ std::invoke(std::forward<F>(f), int{}, int{}) } -> std::convertible_to<std::string>;
};
template <GeomIndexCallable F>
inline void geom_append_joined(std::string& out, int count, std::string_view separator, F&& emit_one) {
for (int i = 0; i < count; ++i) {
if (i > 0) {
out += separator;
}
emit_one(i);
}
}
inline std::string_view geom_field_name(int index) {
return kGeomFieldNames[index];
}
inline std::string geom_vec_name(std::string_view prefix, int n) {
return std::string(prefix) + std::to_string(n);
}
inline std::string geom_mat_name(std::string_view prefix, int cols, int rows) {
if (cols == rows) {
return std::string(prefix) + std::to_string(cols);
}
return std::string(prefix) + std::to_string(cols) + "x" + std::to_string(rows);
}
template <GeomIndexStringCallable F>
inline void geom_append_constructor_call(std::string& out, std::string_view type_name, int count, F&& arg_expression) {
out += std::string(type_name);
out += "(";
geom_append_joined(out, count, ", ", [&](int index) {
out += arg_expression(index);
});
out += ")";
}
template <GeomIndexStringCallable F>
inline void geom_append_vector_return(std::string& out, std::string_view vec_name, int count, F&& component_expression) {
out += " return ";
geom_append_constructor_call(out, vec_name, count, component_expression);
out += ";\n";
}
template <GeomIndexPairStringCallable F>
inline void geom_append_matrix_return(
std::string& out,
std::string_view mat_name,
std::string_view vec_name,
int cols,
int rows,
F&& component_expression) {
out += " return ";
out += std::string(mat_name);
out += "(";
geom_append_joined(out, cols, ", ", [&](int col) {
geom_append_constructor_call(out, vec_name, rows, [&](int row) {
return component_expression(col, row);
});
});
out += ");\n";
}
template <GeomIndexStringCallable F>
inline void geom_append_matrix_column_return(std::string& out, std::string_view mat_name, int cols, F&& column_expression) {
out += " return ";
geom_append_constructor_call(out, mat_name, cols, column_expression);
out += ";\n";
}
inline void geom_append_vector_family(std::string& out, GeomVecFamilySpec spec, int n) {
const std::string vec_name = geom_vec_name(spec.prefix, n);
out += "struct " + vec_name + " {\n";
template <CallableMatCordToStr F>
void codegen_append_matrix(std::string& res, int n, int m, int TABS, F&& emit_elem) {
res += "{\n";
for (int i = 0; i < n; ++i) {
out += " " + std::string(spec.scalar) + " " + std::string(geom_field_name(i)) + ";\n";
res += gen_tabs(TABS + 1) + "{";
for (int j = 0; j < m; j++) {
if (j)
res += ", ";
res += emit_elem(i, j);
}
res += "},\n";
}
out += "\n";
out += " constexpr " + vec_name + "() noexcept = default;\n";
out += " constexpr " + vec_name + "(";
geom_append_joined(out, n, ", ", [&](int index) {
out += std::string(spec.scalar) + " " + std::string(geom_field_name(index));
});
out += ") noexcept : ";
geom_append_joined(out, n, ", ", [&](int index) {
const std::string field = std::string(geom_field_name(index));
out += field + "(" + field + ")";
});
out += " {}\n";
out += "};\n\n";
res += gen_tabs(TABS) + "}";
}
out += "inline " + vec_name + " operator+(" + vec_name + " A, " + vec_name + " B) noexcept {\n";
geom_append_vector_return(out, vec_name, n, [&](int index) {
const std::string field = std::string(geom_field_name(index));
return "A." + field + " + B." + field;
template <CallableMatCordToStr F>
void codegen_append_matrix_long(std::string& res, int n, int m, int TABS, F&& emit_elem) {
res += "{\n" + gen_tabs(TABS + 1);
for (int i = 0; i < n; ++i) {
res += "{\n";
for (int j = 0; j < m; j++) {
res += gen_tabs(TABS + 2) + emit_elem(i, j) + ",\n";
}
res += gen_tabs(TABS + 1) + "}, ";
}
res += "\n" + gen_tabs(TABS) + "}";
}
constexpr std::string vec_field(int ci) {
constexpr std::array<std::string_view, 4> geom_field_names = {"x", "y", "z", "w"};
return std::string(geom_field_names[ci]);
}
void codegen_append_xvecn_binary_operator(std::string& res, const std::string& xvecn, int n, const std::string& op) {
res +=
xvecn + " operator" + op + "(" + xvecn + " A, " + xvecn + " B) noexcept {\n"
SPACE "return " + xvecn + "{";
res += joined_str(n, ", ", [&](int ci) {
return "A." + vec_field(ci) + " " + op + " B." + vec_field(ci);
});
out += "}\n\n";
res += "};\n}\n\n";
}
out += "inline " + vec_name + " operator-(" + vec_name + " A, " + vec_name + " B) noexcept {\n";
geom_append_vector_return(out, vec_name, n, [&](int index) {
const std::string field = std::string(geom_field_name(index));
return "A." + field + " - B." + field;
});
out += "}\n\n";
out += "inline " + vec_name + " operator-(" + vec_name + " A) noexcept {\n";
geom_append_vector_return(out, vec_name, n, [&](int index) {
return "-A." + std::string(geom_field_name(index));
});
out += "}\n\n";
out += "inline " + vec_name + " operator*(" + vec_name + " A, " + std::string(spec.scalar) + " B) noexcept {\n";
geom_append_vector_return(out, vec_name, n, [&](int index) {
return "A." + std::string(geom_field_name(index)) + " * B";
});
out += "}\n\n";
out += "inline " + vec_name + " operator*(" + std::string(spec.scalar) + " A, " + vec_name + " B) noexcept {\n";
out += " return B * A;\n}\n\n";
out += "inline " + vec_name + " operator/(" + vec_name + " A, " + std::string(spec.scalar) + " B) noexcept {\n";
geom_append_vector_return(out, vec_name, n, [&](int index) {
return "A." + std::string(geom_field_name(index)) + " / B";
});
out += "}\n\n";
out += "inline " + vec_name + " operator*(" + vec_name + " A, " + vec_name + " B) noexcept {\n";
geom_append_vector_return(out, vec_name, n, [&](int index) {
const std::string field = std::string(geom_field_name(index));
return "A." + field + " * B." + field;
});
out += "}\n\n";
out += "inline " + std::string(spec.scalar) + " dot(" + vec_name + " A, " + vec_name + " B) noexcept {\n";
out += " return " + [&]() {
std::string expression;
geom_append_joined(expression, n, " + ", [&](int index) {
const std::string field = std::string(geom_field_name(index));
expression += "A." + field + " * B." + field;
void codegen_append_xvecn_class(std::string& res, const std::string& xvec, const std::string& memb, int n,
bool arithmetic, bool real_arithmetic) {
std::string xvecn = std::string(xvec) + std::to_string(n);
res += "struct " + xvecn + " {\n";
for (int ci = 0; ci < n; ci++) {
res += SPACE + memb + " " + vec_field(ci) + ";\n";
}
if (real_arithmetic) {
res += "\n";
res +=
memb + " length() const noexcept {\n"
SPACE "return ";
res += joined_str(n, " + ", [](int ci) {
return vec_field(ci) + " * " + vec_field(ci);
});
return expression;
}() + ";\n}\n\n";
res += ";\n}\n\n";
if (spec.geometric_methods) {
out += "inline " + std::string(spec.scalar) + " length(" + vec_name + " A) noexcept {\n";
out += " return std::sqrt(dot(A, A));\n}\n\n";
out += "inline " + vec_name + " normalize(" + vec_name + " A) noexcept {\n";
out += " return A / length(A);\n}\n\n";
if (n == 3) {
out += "inline " + vec_name + " cross(" + vec_name + " A, " + vec_name + " B) noexcept {\n";
geom_append_vector_return(out, vec_name, 3, [&](int index) {
if (index == 0) {
return "A.y * B.z - A.z * B.y";
}
if (index == 1) {
return "-A.x * B.z + A.z * B.x";
}
return "A.x * B.y - A.y * B.x";
});
out += "}\n\n";
}
}
}
inline void geom_append_vector_and_one(std::string& out, GeomVecFamilySpec spec, int n) {
const std::string vec_name = geom_vec_name(spec.prefix, n);
const std::string vec_next = geom_vec_name(spec.prefix, n + 1);
out += "inline " + vec_next + " and_one(" + vec_name + " A) noexcept {\n";
geom_append_vector_return(out, vec_next, n + 1, [&](int index) {
if (index == n) {
return std::string("1");
}
return "A." + std::string(geom_field_name(index));
});
out += "}\n\n";
}
inline void geom_append_matrix_struct(std::string& out, GeomMatFamilySpec spec, int cols, int rows) {
const std::string mat_name = geom_mat_name(spec.mat_prefix, cols, rows);
const std::string vec_rows = geom_vec_name(spec.vec_prefix, rows);
out += "struct " + mat_name + " {\n";
for (int col = 0; col < cols; ++col) {
out += " " + vec_rows + " " + std::string(geom_field_name(col)) + ";\n";
}
out += "\n";
out += " constexpr " + mat_name + "() noexcept = default;\n";
out += " constexpr " + mat_name + "(";
geom_append_joined(out, cols, ", ", [&](int col) {
out += vec_rows + " " + std::string(geom_field_name(col));
});
out += ") noexcept : ";
geom_append_joined(out, cols, ", ", [&](int col) {
const std::string field = std::string(geom_field_name(col));
out += field + "(" + field + ")";
});
out += " {}\n";
out += "};\n\n";
}
inline void geom_append_matrix_new(std::string& out, GeomMatFamilySpec spec, int cols, int rows) {
const std::string mat_name = geom_mat_name(spec.mat_prefix, cols, rows);
const std::string vec_rows = geom_vec_name(spec.vec_prefix, rows);
out += "inline " + mat_name + " " + mat_name + "_new(";
bool first = true;
for (int row = 0; row < rows; ++row) {
for (int col = 0; col < cols; ++col) {
if (!first) {
out += ", ";
}
first = false;
out += std::string(spec.scalar) + " ";
out += std::string(geom_field_name(col));
out += std::string(geom_field_name(row));
}
}
out += ") noexcept {\n";
geom_append_matrix_return(out, mat_name, vec_rows, cols, rows, [&](int col, int row) {
return std::string(geom_field_name(col)) + std::string(geom_field_name(row));
});
out += "}\n\n";
}
inline void geom_append_matrix_base_operators(std::string& out, GeomMatFamilySpec spec, int cols, int rows) {
const std::string mat_name = geom_mat_name(spec.mat_prefix, cols, rows);
const std::string scalar = std::string(spec.scalar);
const std::string vec_cols = geom_vec_name(spec.vec_prefix, cols);
const std::string vec_rows = geom_vec_name(spec.vec_prefix, rows);
out += "inline " + mat_name + " operator+(" + mat_name + " A, " + mat_name + " B) noexcept {\n";
geom_append_matrix_column_return(out, mat_name, cols, [&](int col) {
const std::string field = std::string(geom_field_name(col));
return "A." + field + " + B." + field;
});
out += "}\n\n";
out += "inline " + mat_name + " operator-(" + mat_name + " A, " + mat_name + " B) noexcept {\n";
geom_append_matrix_column_return(out, mat_name, cols, [&](int col) {
const std::string field = std::string(geom_field_name(col));
return "A." + field + " - B." + field;
});
out += "}\n\n";
out += "inline " + mat_name + " operator-(" + mat_name + " A) noexcept {\n";
geom_append_matrix_column_return(out, mat_name, cols, [&](int col) {
return "-A." + std::string(geom_field_name(col));
});
out += "}\n\n";
out += "inline " + mat_name + " operator*(" + mat_name + " A, " + scalar + " B) noexcept {\n";
geom_append_matrix_column_return(out, mat_name, cols, [&](int col) {
return "A." + std::string(geom_field_name(col)) + " * B";
});
out += "}\n\n";
out += "inline " + mat_name + " operator*(" + scalar + " A, " + mat_name + " B) noexcept {\n";
out += " return B * A;\n}\n\n";
out += "inline " + mat_name + " operator/(" + mat_name + " A, " + scalar + " B) noexcept {\n";
geom_append_matrix_column_return(out, mat_name, cols, [&](int col) {
return "A." + std::string(geom_field_name(col)) + " / B";
});
out += "}\n\n";
out += "inline " + vec_rows + " operator*(" + mat_name + " A, " + vec_cols + " B) noexcept {\n";
geom_append_vector_return(out, vec_rows, rows, [&](int row) {
std::string expression;
geom_append_joined(expression, cols, " + ", [&](int col) {
expression += "A." + std::string(geom_field_name(col));
expression += ".";
expression += std::string(geom_field_name(row));
expression += " * B.";
expression += std::string(geom_field_name(col));
res +=
xvecn + " normalize() const noexcept {\n"
SPACE + memb + " r = 1 / length();\n"
SPACE "return " + xvecn + "{";
res += joined_str(n, ", ", [](int ci) {
return vec_field(ci) + " / r";
});
return expression;
});
out += "}\n\n";
}
inline void geom_append_matrix_transpose(std::string& out, GeomMatFamilySpec spec, int cols, int rows) {
const std::string mat_name = geom_mat_name(spec.mat_prefix, cols, rows);
const std::string mat_transposed = geom_mat_name(spec.mat_prefix, rows, cols);
const std::string vec_cols = geom_vec_name(spec.vec_prefix, cols);
out += "inline " + mat_transposed + " transpose(" + mat_name + " A) noexcept {\n";
geom_append_matrix_return(out, mat_transposed, vec_cols, rows, cols, [&](int new_col, int new_row) {
return "A." + std::string(geom_field_name(new_row)) + "." + std::string(geom_field_name(new_col));
});
out += "}\n\n";
}
inline void geom_append_square_identity(std::string& out, GeomMatFamilySpec spec, int n) {
const std::string mat_name = geom_mat_name(spec.mat_prefix, n, n);
const std::string vec_name = geom_vec_name(spec.vec_prefix, n);
out += "inline constexpr " + mat_name + " " + mat_name + "_E = ";
geom_append_constructor_call(out, mat_name, n, [&](int col) {
std::string column;
geom_append_constructor_call(column, vec_name, n, [&](int row) {
return std::string(col == row ? "1" : "0");
res += "};\n}\n\n";
}
res += "};\n\n";
if (arithmetic) {
res +=
xvecn + " operator-(" + xvecn + " A) noexcept {\n"
SPACE "return " + xvecn + "{";
res += joined_str(n, ", ", [](int ci) {
return "-A." + vec_field(ci);
});
return column;
});
out += ";\n\n";
}
res += "};\n}\n\n";
inline void geom_append_square_outer_product(std::string& out, GeomMatFamilySpec spec, int n) {
const std::string mat_name = geom_mat_name(spec.mat_prefix, n, n);
const std::string vec_name = geom_vec_name(spec.vec_prefix, n);
codegen_append_xvecn_binary_operator(res, xvecn, n, "+");
codegen_append_xvecn_binary_operator(res, xvecn, n, "-");
out += "inline " + mat_name + " outer_product(" + vec_name + " v) noexcept {\n";
geom_append_matrix_return(out, mat_name, vec_name, n, n, [&](int col, int row) {
const std::string col_field = std::string(geom_field_name(col));
return "v." + col_field + " * v." + std::string(geom_field_name(row));
});
out += "}\n\n";
out += "inline " + mat_name + " " + mat_name + "_new_for_proj(" + vec_name + " v) noexcept {\n";
out += " return outer_product(v);\n}\n\n";
}
inline void geom_append_matrix_times_matrix(std::string& out, GeomMatFamilySpec spec, int n, int m, int k) {
const std::string left_name = geom_mat_name(spec.mat_prefix, n, m);
const std::string right_name = geom_mat_name(spec.mat_prefix, k, n);
const std::string result_name = geom_mat_name(spec.mat_prefix, k, m);
const std::string vec_m = geom_vec_name(spec.vec_prefix, m);
out += "inline " + result_name + " operator*(" + left_name + " A, " + right_name + " B) noexcept {\n";
geom_append_matrix_return(out, result_name, vec_m, k, m, [&](int result_col, int result_row) {
std::string expression;
geom_append_joined(expression, n, " + ", [&](int inner) {
expression += "A." + std::string(geom_field_name(inner));
expression += ".";
expression += std::string(geom_field_name(result_row));
expression += " * B.";
expression += std::string(geom_field_name(result_col));
expression += ".";
expression += std::string(geom_field_name(inner));
res +=
xvecn + " operator+(" + xvecn + " A, " + memb + " b) noexcept {\n"
SPACE "return " + xvecn + "{";
res += joined_str(n, ", ", [](int ci) {
return "A." + vec_field(ci) + " + b";
});
return expression;
});
out += "}\n\n";
res += "};\n}\n\n";
res +=
xvecn + " operator-(" + xvecn + " A, " + memb + " b) noexcept {\n"
SPACE "return " + xvecn + "{";
res += joined_str(n, ", ", [](int ci) {
return "A." + vec_field(ci) + " - b";
});
res += "};\n}\n\n";
}
if (real_arithmetic) {
codegen_append_xvecn_binary_operator(res, xvecn, n, "*");
codegen_append_xvecn_binary_operator(res, xvecn, n, "/");
res +=
xvecn + " operator*(" + xvecn + " A, " + memb + " b) noexcept {\n"
SPACE "return " + xvecn + "{";
res += joined_str(n, ", ", [](int ci) {
return "A." + vec_field(ci) + " * b";
});
res += "};\n}\n\n";
res +=
xvecn + " operator/(" + xvecn + " A, " + memb + " b) noexcept {\n"
SPACE + memb + " r = 1 / b;\n"
SPACE "return " + xvecn + "{";
res += joined_str(n, ", ", [](int ci) {
return "A." + vec_field(ci) + " * r";
});
res += "};\n}\n\n";
res +=
memb + " dot(" + xvecn + " A, " + xvecn + " B) noexcept {\n"
SPACE "return ";
res += joined_str(n, " + ", [](int ci) {
return "A." + vec_field(ci) + " * B." + vec_field(ci);
});
res += ";\n}\n\n";
}
}
inline void geom_append_det_function(std::string& out, GeomMatFamilySpec spec, int n) {
const std::string mat_name = geom_mat_name(spec.mat_prefix, n, n);
const std::string scalar = std::string(spec.scalar);
void codegen_append_and_one_func(std::string& res, const std::string& xvec, int n) {
res +=
xvec + std::to_string(n + 1) + " and_one(" + xvec + std::to_string(n) + " A) noexcept {\n"
SPACE "return " + xvec + std::to_string(n + 1) + "{";
for (int ci = 0; ci < n; ci++) {
res += "A." + vec_field(ci) + ", ";
}
res += "1};\n}\n\n";
}
out += "inline " + scalar + " det(" + mat_name + " a) noexcept {\n";
out += " return " + [&]() {
std::string expression;
if (n == 2) {
expression = "a.x.x * a.y.y - a.x.y * a.y.x";
return expression;
std::string get_matrix_name(const std::string& xmat, int n, int m) {
if (n == m)
return xmat + std::to_string(n);
return xmat + std::to_string(n) + "x" + std::to_string(m);
}
void codegen_append_xmatnm_binary_operator(std::string& res, const std::string& xmatnm, int n, int m, const std::string& op) {
res +=
xmatnm + " operator" + op + "(" + xmatnm + " A, " + xmatnm + " B) noexcept {\n"
SPACE "return ";
codegen_append_matrix(res, n, m, 1, [&](int i, int j) {
return "A." + vec_field(i) + "." + vec_field(j) + " " + op + " "
+ "B." + vec_field(i) + "." + vec_field(j);
});
res += ";\n}\n\n";
}
void codegen_append_xmatnm_structure(std::string& res, const std::string& xmat,
const std::string& xvec, const std::string& memb, int n, int m) {
std::string xmatnm = get_matrix_name(xmat, n, m);
std::string xvecm = xvec + std::to_string(m);
res += "struct " + xmatnm + " {\n";
for (int i = 0; i < n; i++) {
res += SPACE + xvecm + " " + vec_field(i) + ";\n";
}
res += "};\n\n";
if (n == m) {
res += "constexpr " + xmatnm + " " + xmatnm + "_E = ";
codegen_append_matrix(res, n, n, 0, [](int i, int j) {
return i == j ? "1" : "0";
});
res += ";\n\n";
}
codegen_append_xmatnm_binary_operator(res, xmatnm, n, m, "+");
codegen_append_xmatnm_binary_operator(res, xmatnm, n, m, "-");
res +=
xmatnm + " operator-" + "(" + xmatnm + " A) noexcept {\n"
SPACE "return ";
codegen_append_matrix(res, n, m, 1, [&](int i, int j) {
return "-A." + vec_field(i) + "." + vec_field(j);
});
res += ";\n}\n\n";
res += "constexpr " + xmatnm + " " + xmatnm + "_new(\n";
res += joined_str(m, ",\n", [&](int y) {
return SPACE + joined_str(n, ", ", [&](int x) {
return memb + " " + vec_field(x) + vec_field(y);
});
});
res += "\n" SPACE "){\n" SPACE "return ";
codegen_append_matrix(res, n, m, 1, [](int x, int y){ return vec_field(x) + vec_field(y); });
res += ";\n}\n\n";
}
void codegen_append_xmatnm_multiplication(std::string& res, const std::string& xmat, int n, int m, int k) {
std::string matnm = get_matrix_name(xmat, n, m);
std::string matkm = get_matrix_name(xmat, k, m);
std::string matkn = get_matrix_name(xmat, k, n);
res += matkm + " operator*(" + matnm + " A, " + matkn + " B) noexcept {\n"
SPACE + "return ";
codegen_append_matrix_long(res, k, m, 1, [&](int x, int y) {
return joined_str(n, " + ", [&](int z) {
return "A." + vec_field(z) + "." + vec_field(y) + " * " + "B." + vec_field(x) + "." + vec_field(z);
});
});
res += ";\n}\n\n";
}
void l1_generate_geom_hpp() {
std::string res;
res += "#pragma once\n"
"/* Automatically generated file. Do not edit it. */\n\n"
"#include <cmath>\n"
"#include <cstdint>\n\n";
for (int n = 2; n <= 4; n++) {
codegen_append_xvecn_class(res, "vec", "float", n, true, true);
codegen_append_xvecn_class(res, "ivec", "int32_t", n, true, false);
codegen_append_xvecn_class(res, "uvec", "uint32_t", n, false, false);
codegen_append_xvecn_class(res, "cvec", "uint8_t", n, false, false);
}
for (int n = 2; n < 4; n++) {
codegen_append_and_one_func(res, "vec", n);
}
for (int n = 2; n <= 4; n++) {
for (int m = 2; m <= 4; m++) {
codegen_append_xmatnm_structure(res, "mat", "vec", "float", n, m);
}
geom_append_joined(expression, n, "\n ", [&](int i) {
if (i > 0) {
expression += "";
}
for (int j = 0; j < n; ++j) {
if (j == i) {
continue;
}
const int k = (n == 3) ? (3 - i - j) : -1;
if (n == 3) {
const bool minus =
(((i > j) ? 1 : 0) + ((j > k) ? 1 : 0) + ((i > k) ? 1 : 0)) % 2 != 0;
if (!expression.empty()) {
expression += " ";
}
expression += minus ? "-" : "+";
expression += " a.x.";
expression += std::string(geom_field_name(i));
expression += " * a.y.";
expression += std::string(geom_field_name(j));
expression += " * a.z.";
expression += std::string(geom_field_name(k));
}
}
if (n == 4) {
for (int j = 0; j < 4; ++j) {
if (j == i) {
continue;
}
for (int k = 0; k < 4; ++k) {
if (k == i || k == j) {
continue;
}
const int u = 6 - i - j - k;
const bool minus =
(((i > j) ? 1 : 0) + ((j > k) ? 1 : 0) + ((i > k) ? 1 : 0) +
((i > u) ? 1 : 0) + ((j > u) ? 1 : 0) + ((k > u) ? 1 : 0)) % 2 != 0;
if (!expression.empty()) {
expression += " ";
}
expression += minus ? "-" : "+";
expression += " a.x.";
expression += std::string(geom_field_name(i));
expression += " * a.y.";
expression += std::string(geom_field_name(j));
expression += " * a.z.";
expression += std::string(geom_field_name(k));
expression += " * a.w.";
expression += std::string(geom_field_name(u));
}
}
}
});
return expression;
}() + ";\n}\n\n";
}
inline std::string geom_build_hpp() {
std::string out;
out.reserve(131072);
out += "#pragma once\n";
out += "/* Automatically generated file. Do not edit it. */\n\n";
out += "#include <cmath>\n";
out += "#include <cstdint>\n\n";
constexpr std::array<GeomVecFamilySpec, 6> vec_specs = {{
{"cvec", "std::uint8_t", false},
{"uvec", "std::uint32_t", false},
{"s64vec", "std::int64_t", false},
{"ivec", "std::int32_t", false},
{"vec", "float", true},
{"dvec", "double", true},
}};
for (const GeomVecFamilySpec& spec : vec_specs) {
for (int n = 2; n <= 4; ++n) {
geom_append_vector_family(out, spec, n);
}
if (spec.geometric_methods) {
for (int n = 2; n <= 3; ++n) {
geom_append_vector_and_one(out, spec, n);
}
for (int n = 2; n <= 4; n++) {
for (int m = 2; m <= 4; m++) {
for (int k = 2; k <= 4; k++) {
codegen_append_xmatnm_multiplication(res, "mat", n, m, k);
}
}
}
for (int n = 2; n <= 4; ++n) {
out += "using s32vec" + std::to_string(n) + " = ivec" + std::to_string(n) + ";\n";
}
out += "\n";
constexpr std::array<GeomMatFamilySpec, 2> mat_specs = {{
{"mat", "vec", "float"},
{"s64mat", "s64vec", "std::int64_t"},
}};
for (const GeomMatFamilySpec& spec : mat_specs) {
for (int cols = 2; cols <= 4; ++cols) {
for (int rows = 2; rows <= 4; ++rows) {
geom_append_matrix_struct(out, spec, cols, rows);
geom_append_matrix_new(out, spec, cols, rows);
geom_append_matrix_base_operators(out, spec, cols, rows);
}
}
for (int cols = 2; cols <= 4; ++cols) {
for (int rows = 2; rows <= 4; ++rows) {
geom_append_matrix_transpose(out, spec, cols, rows);
}
}
for (int n = 2; n <= 4; ++n) {
geom_append_square_identity(out, spec, n);
geom_append_square_outer_product(out, spec, n);
}
for (int n = 2; n <= 4; ++n) {
for (int m = 2; m <= 4; ++m) {
for (int k = 2; k <= 4; ++k) {
geom_append_matrix_times_matrix(out, spec, n, m, k);
}
}
}
for (int n = 2; n <= 4; ++n) {
geom_append_det_function(out, spec, n);
}
}
return out;
}
inline void l1_generate_geom_hpp() {
write_text_file("l1/allie_cpp/geom.hpp", geom_build_hpp());
write_text_file("l1/allie_cpp/geom.hpp", res);
}

View File

@ -6,6 +6,25 @@
#include <string>
#include <string_view>
#define SPACE " "
template <class F>
concept CallableIntToString = requires(F&& f) {
{std::invoke(std::forward<F>(f), int{})} -> std::convertible_to<std::string>;
};
template <CallableIntToString F>
std::string joined_str(int count, std::string_view separator, F&& emit_one) {
std::string res;
for (int i = 0; i < count; ++i) {
if (i > 0) {
res += separator;
}
res += emit_one(i);
}
return res;
}
inline void write_text_file(std::string_view path_string, std::string_view text) {
const std::filesystem::path path(path_string);
std::ofstream out(path);
@ -18,3 +37,7 @@ inline void write_text_file(std::string_view path_string, std::string_view text)
inline void touch_file(std::string_view path_string) {
write_text_file(path_string, "");
}
std::string gen_tabs(int TABS) {
return std::string(TABS * 4, ' ');
}

View File

@ -26,7 +26,7 @@ vec4 funky_color(float time) {
}
vec3 project_dir_onto_plane_xz(vec3 v){
vec2 xz = normalize(vec2(v.x, v.z));
vec2 xz = vec2(v.x, v.z).normalize();
return (vec3){xz.x, 0, xz.y};
}