-
Notifications
You must be signed in to change notification settings - Fork 303
Description
Background
Currently symengine-sys uses bindgen to generate raw C bindings to SymEngine’s C API. Consumers then write their own unsafe wrappers to expose safe, idiomatic Rust types. While this covers the entire C API and regenerates automatically on upstream changes, it comes with:
-
Lots of unsafe boilerplate: every call must be wrapped manually.
-
Potential for pointer/ownership bugs.
-
No native C++ interop: C++-only classes (e.g.
std::vector<Basic>) and exceptions are out of reach.
Proposal
Introduce an rust native alternative bridge using the cxx crate to target SymEngine’s C++ API directly. This would live in a new sub‑crate (e.g. symengine-cxx).
What to expose for a start
-
Core handle types:
-
SymBasic(SymEngine::Basic) -
SymRealDouble(SymEngine::RealDouble) -
SymInteger,SymRational,SymSymboland others
-
-
Essential methods:
-
Constructors / destructors /
clone -
__str__(to RustString) -
Arithmetic:
add,sub,mul,div,pow -
Simplifiers:
simplify,expand,factor -
Numeric functions:
sin,cos,exp,log -
Utility factories:
integer(),symbol() -
Matrix/vector types via
std::vectorandDenseMatrixand others
-
Estimated Effort
Based on ~100 functions + ~10 types × 1 line each, plus grouping comments.
| Piece | Rough Size | Estimated Time |
|---|---|---|
| symengine_cxx.h (C++ alias header) | ~6 lines | 1 day |
| #[cxx::bridge] block | ~120 lines¹ | 2 weeks |
| build.rs integration | ~8 lines | 1 day |
| Smoke tests & examples | ~20 lines + tests | 1 week |
| Total | ~150 lines | ~4 weeks |
Benefits
-
Safe Rust API out of the box: no more
unsafein consumer code. -
Direct C++ interop: leverage C++-only features such as exceptions, STL containers, and class hierarchies.
-
Smaller, explicit surface: bridge file grows linearly (1 line per function), so it’s easy to review and document.
-
Faster incremental builds: only the bridge recompiles on changes.
Drawbacks
-
Manual upkeep: adding or removing API methods requires editing the bridge by hand.
-
Partial coverage: unless we bridge every symbol, some C functions may remain inaccessible.
-
Upfront investment: ~4 weeks of initial work plus ongoing maintenance.
Next Steps
-
Create a
symengine-cxxsub‑crate (or addcxxfeature tosymengine-sys). -
Draft
symengine_cxx.hwith includes andusingaliases. -
Scaffold
#[cxx::bridge]insrc/lib.rsfor a handful of core methods. -
Wire up
build.rswithcxx_build::bridge. -
Add smoke tests and update CI.
-
Iterate: expand coverage, refine ergonomics.