openscad-cpp-evaluator 1.34.0__tar.gz → 1.35.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/.github/workflows/ci.yml +14 -1
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/.github/workflows/wheels.yml +9 -1
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/CMakeLists.txt +9 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/PKG-INFO +1 -1
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/bindings/module.cpp +4 -3
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/value.hpp +63 -4
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/pyproject.toml +1 -1
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/builtins/booleans.cpp +1 -1
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/builtins/function_builtins.cpp +15 -8
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/builtins/primitives_3d.cpp +1 -1
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/expr_eval.cpp +1 -1
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/value.cpp +44 -10
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/CMakeLists.txt +16 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_function_builtins.cpp +9 -9
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_value.cpp +68 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/uv.lock +1 -1
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/.gitignore +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/.gitmodules +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/CLAUDE.md +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/LICENSE +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/README.md +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/bindings/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/bindings/ast_to_py.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/cmake/embed_font.cmake +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/examples/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/examples/eval_perf_benchmark.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/examples/manifold_cache_reuse.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/examples/minimal_debugger.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/.github/workflows/ci.yml +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/.gitignore +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/CLAUDE.md +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/README.md +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/api.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/ast_node.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/comments.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/declarations.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/expression.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/module_instantiation.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/scope_builder.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast/vector_element.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/ast.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/comments.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/position.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/pretty_print.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/scope_table.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/serialization.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/include/openscad_cpp_parser/source_map.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/src/.DS_Store +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/src/api.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/src/ast/ast_node.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/src/ast/declarations.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/src/ast/expression.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/src/ast/format_utils.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/src/ast/module_instantiation.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/src/ast/scope_builder.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/src/ast/vector_element.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/src/comment_attach_internal.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/src/comments.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/src/grammar/driver.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/src/grammar/driver.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/src/grammar/lexer.l +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/src/grammar/lexer_api.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/src/grammar/oscad_location.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/src/grammar/parser.y +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/src/inline_comment_attach.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/src/position.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/src/pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/src/scope.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/src/serialization/json_io.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/src/serialization/yaml_io.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/src/source_map.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/tests/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/tests/test_assignments.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/tests/test_ast_generation.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/tests/test_comments_and_files.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/tests/test_concurrent_parse.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/tests/test_const_borrow.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/tests/test_control.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/tests/test_expressions.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/tests/test_functions.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/tests/test_inline_comments.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/tests/test_lexical.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/tests/test_modules.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/tests/test_node_str.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/tests/test_pretty_print.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/tests/test_render_expression.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/tests/test_scope.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/tests/test_serialization.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/tests/test_smoke.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/tests/test_source_map.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/tests/test_strict_commas.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/tests/test_use_include.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/tests/test_vectors.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/external/openscad_cpp_parser/tools/cli/main.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/bound_args.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/bytecode.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/bytecode_compiler.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/bytecode_vm.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/call_args.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/colored_body.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/coverage.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/csg_node.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/css_colors.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/debug_hooks.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/debug_repl.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/dispatch.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/dxf_svg_import.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/eval_context.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/eval_error.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/eval_use.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/evaluator.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/export.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/font_match.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/font_provider.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/format_closure.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/freetype_font_provider.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/function_builtins.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/import_builtin.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/manifold_cache.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/mesh_check.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/mesh_import.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/osc_range.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/profile.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/scope_trail.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/segments.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/surface_load.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/text_metrics.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/utf8.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/include/openscad_cpp_evaluator/zip_stored.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/python/openscad_cpp_evaluator/__init__.py +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/resources/fonts/LICENSE +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/resources/fonts/LiberationSans-Bold.ttf +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/resources/fonts/LiberationSans-BoldItalic.ttf +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/resources/fonts/LiberationSans-Italic.ttf +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/resources/fonts/LiberationSans-Regular.ttf +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/builtins/builtins.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/builtins/call_args.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/builtins/color.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/builtins/control.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/builtins/dxf_dim.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/builtins/extrude.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/builtins/import.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/builtins/modifiers.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/builtins/primitives_2d.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/builtins/registry.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/builtins/roof.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/builtins/segments.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/builtins/surface.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/builtins/text.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/builtins/topology.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/builtins/transforms.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/bytecode_compiler.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/bytecode_vm.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/colored_body.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/coverage.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/csg_generate.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/csg_resolve.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/css_colors.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/debug/debug_repl.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/debug_profile.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/eval_context.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/eval_error.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/eval_use.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/export.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/format_closure.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/import/dxf_import.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/import/mesh_import.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/import/scene_import.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/import/surface_load.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/import/svg_import.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/measure_geometry.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/mesh_check.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/stmt_eval.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/text/font_match.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/text/freetype_font_provider.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/text/text_metrics.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/user_calls.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/utf8.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/xkcd_colors.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/xkcd_colors.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_booleans.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_bytecode_compiler.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_children_separate.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_cli.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_control_flow.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_coverage.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_csg_tree.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_debug_hooks.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_discretizer.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_dxf_svg_import.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_eval_context.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_export.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_expr_eval.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_extrude_roof.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_feature_detection.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_helpers.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_import_export.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_include_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_manifold_cache.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_mesh_check.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_multi_color_merge.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_primitives.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_profiling.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_python_bindings.py +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_render_expr.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_scope_trail.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_scoping.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_surface.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_tail_calls.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_text.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_transforms.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_unexpected_args.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_use.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_viewport_params.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_zip_stored.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tools/cli/CMakeLists.txt +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tools/cli/cli_lib.cpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tools/cli/cli_lib.hpp +0 -0
- {openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tools/cli/main.cpp +0 -0
|
@@ -50,8 +50,21 @@ jobs:
|
|
|
50
50
|
# Linux/macOS use (CMAKE_BUILD_TYPE already picked the config), but
|
|
51
51
|
# required on Windows's default multi-config Visual Studio
|
|
52
52
|
# generator, which ignores CMAKE_BUILD_TYPE entirely.
|
|
53
|
+
# A bounded job count on the Unix runners. A bare `-j` becomes `make -j`,
|
|
54
|
+
# which starts EVERY compile at once; on macos-latest (3 vCPU, 7 GB) a
|
|
55
|
+
# pile of template-heavy translation units that size ran the build at
|
|
56
|
+
# 852-2000 s against Linux's ~300 s. Windows keeps the bare -j: MSBuild
|
|
57
|
+
# reads it as "use the cores", which is already bounded.
|
|
53
58
|
- name: Build
|
|
54
|
-
|
|
59
|
+
shell: bash
|
|
60
|
+
run: |
|
|
61
|
+
case "$RUNNER_OS" in
|
|
62
|
+
macOS) JOBS=$(sysctl -n hw.ncpu) ;;
|
|
63
|
+
Linux) JOBS=$(nproc) ;;
|
|
64
|
+
*) JOBS= ;;
|
|
65
|
+
esac
|
|
66
|
+
echo "building with -j ${JOBS:-<unbounded: MSBuild>}"
|
|
67
|
+
cmake --build build --config Release -j $JOBS
|
|
55
68
|
|
|
56
69
|
# Bytecode VM on (the default as of the Phase 5 rollout decision --
|
|
57
70
|
# see evaluator.hpp's own bytecodeVmEnabled() comment) and off
|
{openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/.github/workflows/wheels.yml
RENAMED
|
@@ -38,8 +38,16 @@ jobs:
|
|
|
38
38
|
name: macos-arm64
|
|
39
39
|
- runner: macos-15-intel
|
|
40
40
|
name: macos-x86_64
|
|
41
|
+
# Two Windows jobs, one per architecture, both on the x86_64 runner
|
|
42
|
+
# (ARM64 is cross-compiled; see CIBW_ARCHS_WINDOWS). As one job they
|
|
43
|
+
# built one after the other -- 7 min each, 14.5 min for the job,
|
|
44
|
+
# the slowest in the release -- when neither needs the other.
|
|
41
45
|
- runner: windows-latest
|
|
42
46
|
name: windows-x86_64
|
|
47
|
+
archs: AMD64
|
|
48
|
+
- runner: windows-latest
|
|
49
|
+
name: windows-arm64
|
|
50
|
+
archs: ARM64
|
|
43
51
|
runs-on: ${{ matrix.runner }}
|
|
44
52
|
steps:
|
|
45
53
|
- uses: actions/checkout@v7
|
|
@@ -65,7 +73,7 @@ jobs:
|
|
|
65
73
|
# ARM64 build at all, so building on an ARM runner would have to
|
|
66
74
|
# emulate it. cibuildwheel skips CIBW_TEST_COMMAND for the
|
|
67
75
|
# cross-compiled wheel, since an x86_64 host cannot run it.
|
|
68
|
-
CIBW_ARCHS_WINDOWS:
|
|
76
|
+
CIBW_ARCHS_WINDOWS: ${{ matrix.archs }}
|
|
69
77
|
# delvewheel vendors the MSVC runtime into the wheel, but on an
|
|
70
78
|
# x86_64 host it can only find the x86_64 copy -- repairing the
|
|
71
79
|
# cross-built ARM64 wheel died with "Unable to find library:
|
|
@@ -79,6 +79,15 @@ if(MSVC)
|
|
|
79
79
|
# unconditionally (a POSIX extension our code already relies on), so no
|
|
80
80
|
# equivalent is needed there.
|
|
81
81
|
add_compile_definitions(_USE_MATH_DEFINES)
|
|
82
|
+
# /MP: compile a target's source files in parallel. MSBuild's own /m (what
|
|
83
|
+
# `cmake --build -j` passes) runs PROJECTS in parallel but each project's
|
|
84
|
+
# files one at a time, and nearly everything here is one big library, so a
|
|
85
|
+
# Windows build was close to serial (CI's Build step ~665 s against Linux's
|
|
86
|
+
# ~250). Visual Studio generators only: under Ninja every compiler call is
|
|
87
|
+
# already one file, and Ninja does the parallelism itself.
|
|
88
|
+
if(CMAKE_GENERATOR MATCHES "Visual Studio")
|
|
89
|
+
add_compile_options(/MP)
|
|
90
|
+
endif()
|
|
82
91
|
endif()
|
|
83
92
|
|
|
84
93
|
# The nanobind Python extension (bindings/) links the static evaluator lib
|
|
@@ -73,9 +73,10 @@ oscadeval::Value pyToValue(nb::handle v) {
|
|
|
73
73
|
if (nb::isinstance<nb::int_>(v) || nb::isinstance<nb::float_>(v)) return oscadeval::Value{nb::cast<double>(v)};
|
|
74
74
|
if (nb::isinstance<nb::str>(v)) return oscadeval::Value{nb::cast<std::string>(v)};
|
|
75
75
|
if (nb::isinstance<nb::list>(v) || nb::isinstance<nb::tuple>(v)) {
|
|
76
|
-
oscadeval::
|
|
77
|
-
for (nb::handle item : nb::borrow<nb::sequence>(v))
|
|
78
|
-
return oscadeval::Value{oscadeval::ListPtr(
|
|
76
|
+
std::vector<oscadeval::Value> items;
|
|
77
|
+
for (nb::handle item : nb::borrow<nb::sequence>(v)) items.push_back(pyToValue(item));
|
|
78
|
+
return oscadeval::Value{oscadeval::ListPtr(
|
|
79
|
+
std::make_shared<const oscadeval::ValueList>(oscadeval::ValueList{std::move(items)}))};
|
|
79
80
|
}
|
|
80
81
|
return oscadeval::Value{}; // monostate = undef
|
|
81
82
|
}
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
#include "openscad_cpp_evaluator/osc_range.hpp"
|
|
4
4
|
|
|
5
|
+
#include <atomic>
|
|
5
6
|
#include <functional>
|
|
7
|
+
#include <initializer_list>
|
|
6
8
|
#include <memory>
|
|
7
9
|
#include <optional>
|
|
8
10
|
#include <string>
|
|
@@ -98,13 +100,70 @@ inline std::shared_ptr<TrailView<Value>> capturedLetTrail(const Closure& c) {
|
|
|
98
100
|
return std::static_pointer_cast<TrailView<Value>>(c.capturedLet);
|
|
99
101
|
}
|
|
100
102
|
|
|
101
|
-
//
|
|
102
|
-
//
|
|
103
|
-
//
|
|
103
|
+
// A list's elements: a read-only view of the first `size()` elements of a
|
|
104
|
+
// buffer that other lists may share. Lists that are prefixes of one another
|
|
105
|
+
// share one buffer, which is what makes repeated appending cheap: `acc`
|
|
106
|
+
// and `concat(acc, [x])` are the same buffer, the second one element
|
|
107
|
+
// longer (listAppend). Defined after Value so both can hold Value by value
|
|
108
|
+
// -- the standard recursive-variant pattern.
|
|
109
|
+
//
|
|
110
|
+
// The buffer only ever grows within the capacity it was given, so element
|
|
111
|
+
// addresses never move while any view of it is alive, and an element, once
|
|
112
|
+
// written, is never changed. `used` is how far the longest view reaches;
|
|
113
|
+
// only a list ending exactly there may extend it, claiming the new slots
|
|
114
|
+
// with one compare-and-swap, so two lists sharing a prefix can never write
|
|
115
|
+
// the same slot (the loser copies).
|
|
116
|
+
struct ListBuffer {
|
|
117
|
+
std::vector<Value> v;
|
|
118
|
+
std::atomic<size_t> used;
|
|
119
|
+
// Set when this buffer came from appending: a list that was appended
|
|
120
|
+
// to once is likely to be again, so ITS copies grow geometrically,
|
|
121
|
+
// while a one-off concat's result is allocated at exactly its size.
|
|
122
|
+
bool fromAppend = false;
|
|
123
|
+
explicit ListBuffer(std::vector<Value>&& items) : v(std::move(items)), used(v.size()) {}
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
class ListItems {
|
|
127
|
+
public:
|
|
128
|
+
ListItems() = default;
|
|
129
|
+
ListItems(std::vector<Value>&& items) // NOLINT: implicit, as the old vector was
|
|
130
|
+
: buf_(std::make_shared<ListBuffer>(std::move(items))), n_(buf_->v.size()) {}
|
|
131
|
+
ListItems(const std::vector<Value>& items) : ListItems(std::vector<Value>(items)) {} // NOLINT
|
|
132
|
+
ListItems(std::initializer_list<Value> items) : ListItems(std::vector<Value>(items)) {}
|
|
133
|
+
|
|
134
|
+
size_t size() const { return n_; }
|
|
135
|
+
bool empty() const { return n_ == 0; }
|
|
136
|
+
const Value* data() const { return buf_ ? buf_->v.data() : nullptr; }
|
|
137
|
+
const Value* begin() const { return data(); }
|
|
138
|
+
const Value* end() const { return data() + n_; }
|
|
139
|
+
const Value& operator[](size_t i) const { return data()[i]; }
|
|
140
|
+
const Value& at(size_t i) const;
|
|
141
|
+
const Value& front() const { return data()[0]; }
|
|
142
|
+
const Value& back() const { return data()[n_ - 1]; }
|
|
143
|
+
// A copy as a plain vector, for the few callers that build on one.
|
|
144
|
+
// Explicit, so a copy is never made by accident binding a reference.
|
|
145
|
+
explicit operator std::vector<Value>() const { return std::vector<Value>(begin(), end()); }
|
|
146
|
+
std::vector<Value> toVector() const { return std::vector<Value>(begin(), end()); }
|
|
147
|
+
|
|
148
|
+
private:
|
|
149
|
+
ListItems(std::shared_ptr<ListBuffer> buf, size_t n) : buf_(std::move(buf)), n_(n) {}
|
|
150
|
+
std::shared_ptr<ListBuffer> buf_;
|
|
151
|
+
size_t n_ = 0;
|
|
152
|
+
friend ListPtr listAppend(const ListPtr& base, std::vector<Value>&& extra);
|
|
153
|
+
};
|
|
154
|
+
|
|
104
155
|
struct ValueList {
|
|
105
|
-
|
|
156
|
+
ListItems items;
|
|
106
157
|
};
|
|
107
158
|
|
|
159
|
+
// `base` followed by `extra`, sharing base's buffer whenever base is the
|
|
160
|
+
// longest list using it and the buffer has room: amortized O(|extra|)
|
|
161
|
+
// rather than O(|base| + |extra|), which is what turns the idiomatic
|
|
162
|
+
// tail-recursive accumulator, f(i, concat(acc, [x])), from quadratic into
|
|
163
|
+
// linear. Safe whatever else still holds `base`: base keeps seeing only
|
|
164
|
+
// its own elements.
|
|
165
|
+
ListPtr listAppend(const ListPtr& base, std::vector<Value>&& extra);
|
|
166
|
+
|
|
108
167
|
// Insertion-ordered key/value pairs, not a map: object()'s iteration order
|
|
109
168
|
// and `==` are order-sensitive (doc: openscad_evaluator/docs/evaluator.md,
|
|
110
169
|
// the object() entry).
|
|
@@ -313,7 +313,7 @@ std::vector<ColoredBody> generateCsg(Evaluator& ev, const CSGParams& params, con
|
|
|
313
313
|
const std::string& op = std::get<std::string>(params.at("op"));
|
|
314
314
|
const auto& groupSizes = std::get<ListPtr>(params.at("group_sizes"))->items;
|
|
315
315
|
const auto emptyIsAGroupIt = params.find("empty_is_a_group");
|
|
316
|
-
const
|
|
316
|
+
const ListItems* emptyIsAGroup =
|
|
317
317
|
emptyIsAGroupIt == params.end()
|
|
318
318
|
? nullptr
|
|
319
319
|
: &std::get<ListPtr>(emptyIsAGroupIt->second)->items;
|
{openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/builtins/function_builtins.cpp
RENAMED
|
@@ -616,11 +616,11 @@ Value builtinSearch(const CallArgs& args, Evaluator& ev, const oscad::Position*
|
|
|
616
616
|
const unsigned numReturns = static_cast<unsigned>(static_cast<long long>(nrRaw));
|
|
617
617
|
const unsigned indexCol = static_cast<unsigned>(static_cast<long long>(icRaw));
|
|
618
618
|
|
|
619
|
-
static const
|
|
619
|
+
static const ListItems kNoItems;
|
|
620
620
|
const ListPtr* tablePtr = std::get_if<ListPtr>(&tableArg);
|
|
621
|
-
const
|
|
621
|
+
const ListItems& table = (tablePtr && *tablePtr) ? (*tablePtr)->items : kNoItems;
|
|
622
622
|
|
|
623
|
-
const auto itemsOf = [](const Value& v) -> const
|
|
623
|
+
const auto itemsOf = [](const Value& v) -> const ListItems& {
|
|
624
624
|
const ListPtr* l = std::get_if<ListPtr>(&v);
|
|
625
625
|
return (l && *l) ? (*l)->items : kNoItems;
|
|
626
626
|
};
|
|
@@ -629,7 +629,7 @@ Value builtinSearch(const CallArgs& args, Evaluator& ev, const oscad::Position*
|
|
|
629
629
|
// only when the entry really is a long enough vector.
|
|
630
630
|
const auto hits = [&](const Value& needle, const Value& entry) {
|
|
631
631
|
if (indexCol == 0 && oscEqual(needle, entry)) return true;
|
|
632
|
-
const
|
|
632
|
+
const ListItems& ev2 = itemsOf(entry);
|
|
633
633
|
return indexCol < ev2.size() && oscEqual(needle, ev2[indexCol]);
|
|
634
634
|
};
|
|
635
635
|
const auto num = [](size_t j) { return Value{static_cast<double>(j)}; };
|
|
@@ -682,7 +682,7 @@ Value builtinSearch(const CallArgs& args, Evaluator& ev, const oscad::Position*
|
|
|
682
682
|
unsigned matchCount = 0;
|
|
683
683
|
std::vector<Value> resultvec;
|
|
684
684
|
for (size_t j = 0; j < table.size(); ++j) {
|
|
685
|
-
const
|
|
685
|
+
const ListItems& entryVec = itemsOf(table[j]);
|
|
686
686
|
if (entryVec.size() <= indexCol) {
|
|
687
687
|
ev.warn("Invalid entry in search vector at index " + std::to_string(j) +
|
|
688
688
|
", required number of values in the entry: " + std::to_string(indexCol + 1) +
|
|
@@ -1162,9 +1162,9 @@ bool checkMinMax(Evaluator& ev, const std::string& name, const CallArgs& args, c
|
|
|
1162
1162
|
return false;
|
|
1163
1163
|
}
|
|
1164
1164
|
if (nPos == 1 && std::holds_alternative<ListPtr>(positionalAt(args, 0))) {
|
|
1165
|
-
static const
|
|
1165
|
+
static const ListItems kEmptyItems;
|
|
1166
1166
|
const ListPtr& l = std::get<ListPtr>(positionalAt(args, 0));
|
|
1167
|
-
const
|
|
1167
|
+
const ListItems& items = l ? l->items : kEmptyItems;
|
|
1168
1168
|
if (items.empty()) {
|
|
1169
1169
|
warnArity(ev, name, "at least 1 vector element", 0, pos);
|
|
1170
1170
|
return false;
|
|
@@ -1346,14 +1346,21 @@ Value evalBuiltinFunctionResolved(Evaluator& ev, BuiltinFnId id, const std::vect
|
|
|
1346
1346
|
toDoubleLenient(getArg(args, 2, "value_count", Value{})), getArg(args, 3, "seed", Value{}));
|
|
1347
1347
|
}
|
|
1348
1348
|
case BuiltinFnId::Concat: {
|
|
1349
|
+
// Everything after the first argument, appended to the first
|
|
1350
|
+
// when it is a list: listAppend extends its buffer in place when
|
|
1351
|
+
// it can, so an accumulator loop is linear, not quadratic.
|
|
1352
|
+
const size_t count = positionalCount(args);
|
|
1353
|
+
const ListPtr* first = count ? std::get_if<ListPtr>(&positionalAt(args, 0)) : nullptr;
|
|
1349
1354
|
std::vector<Value> out;
|
|
1350
|
-
for (
|
|
1355
|
+
for (size_t i = (first && *first) ? 1 : 0; i < count; ++i) {
|
|
1356
|
+
const Value& a = positionalAt(args, i);
|
|
1351
1357
|
if (const ListPtr* l = std::get_if<ListPtr>(&a); l && *l) {
|
|
1352
1358
|
out.insert(out.end(), (*l)->items.begin(), (*l)->items.end());
|
|
1353
1359
|
} else {
|
|
1354
1360
|
out.push_back(a);
|
|
1355
1361
|
}
|
|
1356
1362
|
}
|
|
1363
|
+
if (first && *first) return Value{listAppend(*first, std::move(out))};
|
|
1357
1364
|
return listOf(std::move(out));
|
|
1358
1365
|
}
|
|
1359
1366
|
case BuiltinFnId::Len: {
|
{openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/src/builtins/primitives_3d.cpp
RENAMED
|
@@ -133,7 +133,7 @@ CSGParams resolveCube(Evaluator& ev, const oscad::ModularCall& node, EvalContext
|
|
|
133
133
|
} else if (l && *l && (*l)->items.size() == 3 &&
|
|
134
134
|
std::all_of((*l)->items.begin(), (*l)->items.end(),
|
|
135
135
|
[](const Value& v) { return std::holds_alternative<double>(v); })) {
|
|
136
|
-
sizeVec = (*l)->items;
|
|
136
|
+
sizeVec = (*l)->items.toVector();
|
|
137
137
|
} else if (!std::holds_alternative<std::monostate>(sizeArg)) {
|
|
138
138
|
ev.warn("Unable to convert cube(size=" + fmtValue(sizeArg) +
|
|
139
139
|
", ...) parameter to a number or a vec3 of numbers",
|
|
@@ -42,7 +42,7 @@ std::optional<bool> valueLess(const Value& a, const Value& b) {
|
|
|
42
42
|
|
|
43
43
|
const ListPtr& la = std::get<ListPtr>(a);
|
|
44
44
|
const ListPtr& lb = std::get<ListPtr>(b);
|
|
45
|
-
static const
|
|
45
|
+
static const ListItems kEmpty;
|
|
46
46
|
const auto& ia = la ? la->items : kEmpty;
|
|
47
47
|
const auto& ib = lb ? lb->items : kEmpty;
|
|
48
48
|
const size_t n = std::min(ia.size(), ib.size());
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
#include <limits>
|
|
9
9
|
#include <optional>
|
|
10
10
|
#include <sstream>
|
|
11
|
+
#include <stdexcept>
|
|
11
12
|
|
|
12
13
|
namespace oscadeval {
|
|
13
14
|
|
|
@@ -205,8 +206,8 @@ namespace {
|
|
|
205
206
|
// matrix*matrix branch of multiply_visitor -- including which check fires
|
|
206
207
|
// first, since that decides which diagnostic a malformed operand produces.
|
|
207
208
|
// `fail` records the message and returns undef.
|
|
208
|
-
const
|
|
209
|
-
static const
|
|
209
|
+
const ListItems& itemsOf(const Value& v) {
|
|
210
|
+
static const ListItems kEmpty;
|
|
210
211
|
const ListPtr* l = std::get_if<ListPtr>(&v);
|
|
211
212
|
return (l && *l) ? (*l)->items : kEmpty;
|
|
212
213
|
}
|
|
@@ -219,7 +220,7 @@ Value fail(std::string* error, std::string message) {
|
|
|
219
220
|
}
|
|
220
221
|
|
|
221
222
|
// Vector dot product. Sizes are equal by the caller's own check.
|
|
222
|
-
Value multVecVec(const
|
|
223
|
+
Value multVecVec(const ListItems& v1, const ListItems& v2, std::string* error) {
|
|
223
224
|
double r = 0.0;
|
|
224
225
|
for (size_t i = 0; i < v1.size(); ++i) {
|
|
225
226
|
if (!isNum(v1[i]) || !isNum(v2[i])) {
|
|
@@ -230,11 +231,11 @@ Value multVecVec(const std::vector<Value>& v1, const std::vector<Value>& v2, std
|
|
|
230
231
|
return Value{r};
|
|
231
232
|
}
|
|
232
233
|
|
|
233
|
-
Value multMatVec(const
|
|
234
|
+
Value multMatVec(const ListItems& mat, const ListItems& vec, std::string* error) {
|
|
234
235
|
std::vector<Value> out;
|
|
235
236
|
out.reserve(mat.size());
|
|
236
237
|
for (size_t i = 0; i < mat.size(); ++i) {
|
|
237
|
-
const
|
|
238
|
+
const ListItems& row = itemsOf(mat[i]);
|
|
238
239
|
if (!isVec(mat[i]) || row.size() != vec.size()) {
|
|
239
240
|
return fail(error, "Matrix must be rectangular. Problem at row " + std::to_string(i));
|
|
240
241
|
}
|
|
@@ -254,14 +255,14 @@ Value multMatVec(const std::vector<Value>& mat, const std::vector<Value>& vec, s
|
|
|
254
255
|
return makeList(std::move(out));
|
|
255
256
|
}
|
|
256
257
|
|
|
257
|
-
Value multVecMat(const
|
|
258
|
+
Value multVecMat(const ListItems& vec, const ListItems& mat, std::string* error) {
|
|
258
259
|
const size_t firstRowSize = itemsOf(mat[0]).size();
|
|
259
260
|
std::vector<Value> out;
|
|
260
261
|
out.reserve(firstRowSize);
|
|
261
262
|
for (size_t i = 0; i < firstRowSize; ++i) {
|
|
262
263
|
double re = 0.0;
|
|
263
264
|
for (size_t j = 0; j < vec.size(); ++j) {
|
|
264
|
-
const
|
|
265
|
+
const ListItems& row = itemsOf(mat[j]);
|
|
265
266
|
if (!isVec(mat[j]) || row.size() != firstRowSize) {
|
|
266
267
|
return fail(error, "Matrix must be rectangular. Problem at row " + std::to_string(j));
|
|
267
268
|
}
|
|
@@ -282,8 +283,8 @@ Value multVecMat(const std::vector<Value>& vec, const std::vector<Value>& mat, s
|
|
|
282
283
|
} // namespace
|
|
283
284
|
|
|
284
285
|
Value matmul(const Value& a, const Value& b, std::string* error) {
|
|
285
|
-
const
|
|
286
|
-
const
|
|
286
|
+
const ListItems& al = itemsOf(a);
|
|
287
|
+
const ListItems& bl = itemsOf(b);
|
|
287
288
|
// The reference checks emptiness before anything else, so `[] * [1,2]`
|
|
288
289
|
// is this message rather than a length mismatch.
|
|
289
290
|
if (al.empty() || bl.empty()) return fail(error, "Multiplication is undefined on empty vectors");
|
|
@@ -323,7 +324,7 @@ Value matmul(const Value& a, const Value& b, std::string* error) {
|
|
|
323
324
|
std::vector<Value> rows;
|
|
324
325
|
rows.reserve(al.size());
|
|
325
326
|
for (size_t i = 0; i < al.size(); ++i) {
|
|
326
|
-
const
|
|
327
|
+
const ListItems& srcRow = itemsOf(al[i]);
|
|
327
328
|
if (srcRow.size() != bl.size()) {
|
|
328
329
|
return fail(error,
|
|
329
330
|
"matrix*matrix left operand row length does not match right operand row count (" +
|
|
@@ -618,4 +619,37 @@ void appendEachInto(std::vector<Value>& out, const Value& v) {
|
|
|
618
619
|
if (!std::holds_alternative<std::monostate>(v)) out.push_back(v);
|
|
619
620
|
}
|
|
620
621
|
|
|
622
|
+
const Value& ListItems::at(size_t i) const {
|
|
623
|
+
if (i >= n_) throw std::out_of_range("list index out of range");
|
|
624
|
+
return data()[i];
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
ListPtr listAppend(const ListPtr& base, std::vector<Value>&& extra) {
|
|
628
|
+
if (!base) return std::make_shared<const ValueList>(ValueList{std::move(extra)});
|
|
629
|
+
if (extra.empty()) return base;
|
|
630
|
+
const ListItems& items = base->items;
|
|
631
|
+
const size_t n = items.n_, k = extra.size();
|
|
632
|
+
if (const auto& buf = items.buf_; buf && buf->v.capacity() - n >= k) {
|
|
633
|
+
size_t expected = n;
|
|
634
|
+
if (buf->used.compare_exchange_strong(expected, n + k)) {
|
|
635
|
+
// This list ended at the buffer's frontier and now owns the
|
|
636
|
+
// slots after it. Within capacity, push_back never reallocates,
|
|
637
|
+
// so every other view's elements stay where they are.
|
|
638
|
+
for (Value& x : extra) buf->v.push_back(std::move(x));
|
|
639
|
+
return std::make_shared<const ValueList>(ValueList{ListItems(buf, n + k)});
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
// Copy: a fresh buffer, given room to grow if this list has been
|
|
643
|
+
// appended to before (the accumulator case), exact otherwise.
|
|
644
|
+
const bool growing = items.buf_ && items.buf_->fromAppend;
|
|
645
|
+
std::vector<Value> out;
|
|
646
|
+
out.reserve(growing ? std::max<size_t>(2 * (n + k), 16) : n + k);
|
|
647
|
+
out.insert(out.end(), items.begin(), items.end());
|
|
648
|
+
for (Value& x : extra) out.push_back(std::move(x));
|
|
649
|
+
auto buf = std::make_shared<ListBuffer>(std::move(out));
|
|
650
|
+
buf->fromAppend = true;
|
|
651
|
+
const size_t len = buf->v.size();
|
|
652
|
+
return std::make_shared<const ValueList>(ValueList{ListItems(std::move(buf), len)});
|
|
653
|
+
}
|
|
654
|
+
|
|
621
655
|
} // namespace oscadeval
|
|
@@ -48,6 +48,22 @@ add_executable(oscad_eval_tests
|
|
|
48
48
|
# put the archive on the link line twice ("ld: warning: ignoring duplicate
|
|
49
49
|
# libraries").
|
|
50
50
|
target_link_libraries(oscad_eval_tests PRIVATE oscad_cli_lib GTest::gtest_main)
|
|
51
|
+
# Every test file includes gtest and nearly all include evaluator.hpp; parsing
|
|
52
|
+
# those again for each of 35 files was 40-52% of a test file's compile time.
|
|
53
|
+
# One precompiled header takes that off all of them -- the test executable is
|
|
54
|
+
# the last stage of every build and, on MSVC, the longest (~178 s of CI's
|
|
55
|
+
# Windows build).
|
|
56
|
+
target_precompile_headers(oscad_eval_tests PRIVATE
|
|
57
|
+
<gtest/gtest.h>
|
|
58
|
+
<openscad_cpp_evaluator/evaluator.hpp>
|
|
59
|
+
<openscad_cpp_parser/api.hpp>
|
|
60
|
+
<algorithm>
|
|
61
|
+
<cmath>
|
|
62
|
+
<filesystem>
|
|
63
|
+
<fstream>
|
|
64
|
+
<set>
|
|
65
|
+
<string>
|
|
66
|
+
<vector>)
|
|
51
67
|
# stb_image_write.h, used only by this test binary to generate a PNG
|
|
52
68
|
# fixture for ToRenderableBodies/surface() image-loading tests.
|
|
53
69
|
target_include_directories(oscad_eval_tests PRIVATE ${stb_SOURCE_DIR})
|
{openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/tests/test_function_builtins.cpp
RENAMED
|
@@ -23,7 +23,7 @@ double asNum(const Value& v) { return std::get<double>(v); }
|
|
|
23
23
|
bool asBool(const Value& v) { return std::get<bool>(v); }
|
|
24
24
|
bool isUndef(const Value& v) { return std::holds_alternative<std::monostate>(v); }
|
|
25
25
|
std::string asStr(const Value& v) { return std::get<std::string>(v); }
|
|
26
|
-
const
|
|
26
|
+
const ListItems& asList(const Value& v) { return std::get<ListPtr>(v)->items; }
|
|
27
27
|
|
|
28
28
|
} // namespace
|
|
29
29
|
|
|
@@ -742,7 +742,7 @@ TEST(LinearSolve, SolvesASquareSystem) {
|
|
|
742
742
|
// asList() returns a reference INTO v, so v has to outlive it -- taking
|
|
743
743
|
// asList(evalSrc(...)) directly dangles the moment the temporary dies.
|
|
744
744
|
const Value v = evalSrc("linear_solve([[2,1],[1,3]], [5,10]).x", ev);
|
|
745
|
-
const
|
|
745
|
+
const ListItems& x = asList(v);
|
|
746
746
|
ASSERT_EQ(x.size(), 2u);
|
|
747
747
|
EXPECT_NEAR(asNum(x[0]), 1.0, 1e-12);
|
|
748
748
|
EXPECT_NEAR(asNum(x[1]), 3.0, 1e-12);
|
|
@@ -779,7 +779,7 @@ TEST(LinearSolve, SingularityIsRelativeToTheMatrixNotAbsolute) {
|
|
|
779
779
|
Evaluator ev;
|
|
780
780
|
EXPECT_FALSE(asBool(evalSrc("linear_solve([[2e-10,0],[0,2e-10]], [1e-10,1e-10]).singular", ev)));
|
|
781
781
|
const Value v = evalSrc("linear_solve([[2e-10,0],[0,2e-10]], [1e-10,1e-10]).x", ev);
|
|
782
|
-
const
|
|
782
|
+
const ListItems& x = asList(v);
|
|
783
783
|
ASSERT_EQ(x.size(), 2u);
|
|
784
784
|
EXPECT_NEAR(asNum(x[0]), 0.5, 1e-9);
|
|
785
785
|
}
|
|
@@ -789,9 +789,9 @@ TEST(LinearSolve, AMatrixRightHandSideSolvesEveryColumn) {
|
|
|
789
789
|
// Solving against the identity is the inverse; [[2,1],[1,3]] has
|
|
790
790
|
// det 5, so the inverse is [[0.6,-0.2],[-0.2,0.4]].
|
|
791
791
|
const Value v = evalSrc("linear_solve([[2,1],[1,3]], [[1,0],[0,1]]).x", ev);
|
|
792
|
-
const
|
|
792
|
+
const ListItems& rows = asList(v);
|
|
793
793
|
ASSERT_EQ(rows.size(), 2u);
|
|
794
|
-
const
|
|
794
|
+
const ListItems& r0 = asList(rows[0]);
|
|
795
795
|
ASSERT_EQ(r0.size(), 2u);
|
|
796
796
|
EXPECT_NEAR(asNum(r0[0]), 0.6, 1e-12);
|
|
797
797
|
EXPECT_NEAR(asNum(r0[1]), -0.2, 1e-12);
|
|
@@ -814,7 +814,7 @@ TEST(LinearSolve, OverdeterminedGivesTheLeastSquaresFit) {
|
|
|
814
814
|
// y = 1 + 2x, so the residual is zero and a=1, b=2.
|
|
815
815
|
Evaluator ev;
|
|
816
816
|
const Value v = evalSrc("linear_solve([[1,0],[1,1],[1,2],[1,3]], [1,3,5,7]).x", ev);
|
|
817
|
-
const
|
|
817
|
+
const ListItems& x = asList(v);
|
|
818
818
|
ASSERT_EQ(x.size(), 2u);
|
|
819
819
|
EXPECT_NEAR(asNum(x[0]), 1.0, 1e-10);
|
|
820
820
|
EXPECT_NEAR(asNum(x[1]), 2.0, 1e-10);
|
|
@@ -826,7 +826,7 @@ TEST(LinearSolve, OverdeterminedWithNoExactSolutionMinimisesTheResidual) {
|
|
|
826
826
|
// read off this implementation.
|
|
827
827
|
Evaluator ev;
|
|
828
828
|
const Value v = evalSrc("linear_solve([[1,0],[1,1],[1,2],[1,3]], [0,1,2,10]).x", ev);
|
|
829
|
-
const
|
|
829
|
+
const ListItems& x = asList(v);
|
|
830
830
|
ASSERT_EQ(x.size(), 2u);
|
|
831
831
|
EXPECT_NEAR(asNum(x[0]), -1.4, 1e-9);
|
|
832
832
|
EXPECT_NEAR(asNum(x[1]), 3.1, 1e-9);
|
|
@@ -838,7 +838,7 @@ TEST(LinearSolve, UnderdeterminedGivesTheMinimUmNormSolution) {
|
|
|
838
838
|
// asserts the NORM -- that is the whole claim of a minimum-norm solve.
|
|
839
839
|
Evaluator ev;
|
|
840
840
|
const Value v = evalSrc("linear_solve([[1,1]], [2]).x", ev);
|
|
841
|
-
const
|
|
841
|
+
const ListItems& x = asList(v);
|
|
842
842
|
ASSERT_EQ(x.size(), 2u);
|
|
843
843
|
EXPECT_NEAR(asNum(x[0]), 1.0, 1e-12);
|
|
844
844
|
EXPECT_NEAR(asNum(x[1]), 1.0, 1e-12);
|
|
@@ -848,7 +848,7 @@ TEST(LinearSolve, UnderdeterminedSatisfiesEveryEquation) {
|
|
|
848
848
|
// 2 x 3: the plane_intersection shape BOSL2 relies on.
|
|
849
849
|
Evaluator ev;
|
|
850
850
|
const Value v = evalSrc("linear_solve([[1,0,1],[0,1,1]], [3,5]).x", ev);
|
|
851
|
-
const
|
|
851
|
+
const ListItems& x = asList(v);
|
|
852
852
|
ASSERT_EQ(x.size(), 3u);
|
|
853
853
|
const double a = asNum(x[0]), b = asNum(x[1]), c = asNum(x[2]);
|
|
854
854
|
EXPECT_NEAR(a + c, 3.0, 1e-12);
|
|
@@ -607,3 +607,71 @@ TEST(StringEscapes, ABackslashBeforeANewlineTakesTheWholeLineEnding) {
|
|
|
607
607
|
EXPECT_EQ(unescapeStringLiteral("x\\\r\ny"), "xy"); // reference keeps the CR
|
|
608
608
|
EXPECT_EQ(unescapeStringLiteral("x\\\ry"), "xy");
|
|
609
609
|
}
|
|
610
|
+
|
|
611
|
+
// --- listAppend: lists that are prefixes of one another share a buffer ---
|
|
612
|
+
|
|
613
|
+
namespace {
|
|
614
|
+
ListPtr numsList(std::initializer_list<double> xs) {
|
|
615
|
+
std::vector<Value> v;
|
|
616
|
+
for (double x : xs) v.push_back(Value{x});
|
|
617
|
+
return std::make_shared<const ValueList>(ValueList{std::move(v)});
|
|
618
|
+
}
|
|
619
|
+
std::vector<double> nums(const ListPtr& l) {
|
|
620
|
+
std::vector<double> out;
|
|
621
|
+
for (const Value& v : l->items) out.push_back(std::get<double>(v));
|
|
622
|
+
return out;
|
|
623
|
+
}
|
|
624
|
+
std::vector<Value> one(double x) { return {Value{x}}; }
|
|
625
|
+
} // namespace
|
|
626
|
+
|
|
627
|
+
TEST(ListAppend, LeavesTheBaseListAsItWas) {
|
|
628
|
+
const ListPtr base = numsList({1, 2});
|
|
629
|
+
const ListPtr longer = listAppend(base, one(3));
|
|
630
|
+
EXPECT_EQ(nums(base), (std::vector<double>{1, 2}));
|
|
631
|
+
EXPECT_EQ(nums(longer), (std::vector<double>{1, 2, 3}));
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
TEST(ListAppend, AnAccumulatorCopiesOnlyLogarithmicallyOften) {
|
|
635
|
+
// Appends extend the same storage in place, copying only when it fills
|
|
636
|
+
// and then into double the room: 10,000 appends, a handful of copies --
|
|
637
|
+
// where copying every time (the old concat) made the loop quadratic.
|
|
638
|
+
ListPtr acc = numsList({0});
|
|
639
|
+
int copies = 0;
|
|
640
|
+
for (int i = 1; i < 10000; ++i) {
|
|
641
|
+
const ListPtr next = listAppend(acc, one(i));
|
|
642
|
+
if (next->items.data() != acc->items.data()) ++copies;
|
|
643
|
+
acc = next; // the previous list is still alive here, as in a call chain
|
|
644
|
+
}
|
|
645
|
+
EXPECT_LE(copies, 12);
|
|
646
|
+
ASSERT_EQ(acc->items.size(), 10000u);
|
|
647
|
+
for (size_t i = 0; i < 10000; ++i) EXPECT_EQ(std::get<double>(acc->items[i]), double(i));
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
TEST(ListAppend, TwoBranchesFromOnePrefixStayApart) {
|
|
651
|
+
// Only the list ending at the buffer's frontier may extend it; a second
|
|
652
|
+
// extension of the same prefix must copy rather than overwrite the
|
|
653
|
+
// first one's element.
|
|
654
|
+
const ListPtr base = listAppend(listAppend(numsList({0}), one(1)), one(2)); // has spare capacity
|
|
655
|
+
const ListPtr a = listAppend(base, one(10));
|
|
656
|
+
const ListPtr b = listAppend(base, one(20));
|
|
657
|
+
EXPECT_EQ(nums(a), (std::vector<double>{0, 1, 2, 10}));
|
|
658
|
+
EXPECT_EQ(nums(b), (std::vector<double>{0, 1, 2, 20}));
|
|
659
|
+
EXPECT_EQ(nums(base), (std::vector<double>{0, 1, 2}));
|
|
660
|
+
// ...and each branch can go on growing independently.
|
|
661
|
+
EXPECT_EQ(nums(listAppend(a, one(11))), (std::vector<double>{0, 1, 2, 10, 11}));
|
|
662
|
+
EXPECT_EQ(nums(listAppend(b, one(21))), (std::vector<double>{0, 1, 2, 20, 21}));
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
TEST(ListAppend, AOneOffConcatIsAllocatedExactly) {
|
|
666
|
+
// Only a list that has been appended to grows geometrically, so a plain
|
|
667
|
+
// concat(a, b) costs no spare memory.
|
|
668
|
+
const ListPtr r = listAppend(numsList({1, 2, 3}), one(4));
|
|
669
|
+
EXPECT_EQ(r->items.size(), 4u);
|
|
670
|
+
EXPECT_EQ(nums(r), (std::vector<double>{1, 2, 3, 4}));
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
TEST(ListAppend, EmptyExtraAndNullBase) {
|
|
674
|
+
const ListPtr base = numsList({1});
|
|
675
|
+
EXPECT_EQ(listAppend(base, {}), base);
|
|
676
|
+
EXPECT_EQ(nums(listAppend(nullptr, one(5))), (std::vector<double>{5}));
|
|
677
|
+
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/examples/eval_perf_benchmark.cpp
RENAMED
|
File without changes
|
{openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/examples/manifold_cache_reuse.cpp
RENAMED
|
File without changes
|
{openscad_cpp_evaluator-1.34.0 → openscad_cpp_evaluator-1.35.0}/examples/minimal_debugger.cpp
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|