|
| 1 | +# Plan: Reduce `Variant` Boilerplate in `eos_variant.hpp` |
| 2 | + |
| 3 | +## Goal |
| 4 | + |
| 5 | +Reduce duplication in `singularity-eos/eos/eos_variant.hpp` by introducing a small set of helper macros for the repeated `PortsOfCall::visit(...)` wrappers, without changing the public API of `Variant`. |
| 6 | + |
| 7 | +## Summary |
| 8 | + |
| 9 | +A macro-based cleanup should work well in `eos_variant.hpp`. |
| 10 | + |
| 11 | +The vector section is especially repetitive and appears to be a better fit for macros than the already-refactored `EosBase` vector wrappers. Most methods repeat the same four-overload bundle: |
| 12 | + |
| 13 | +1. a no-lambda overload that constructs `NullIndexer` |
| 14 | +2. a lambda-taking overload that dispatches through `PortsOfCall::visit` |
| 15 | +3. a `scratch` + no-lambda overload that constructs `NullIndexer` |
| 16 | +4. a `scratch` + lambda-taking overload that dispatches through `PortsOfCall::visit` |
| 17 | + |
| 18 | +## Recommended Macro Families |
| 19 | + |
| 20 | +### 1. Vector wrappers |
| 21 | + |
| 22 | +Use a small family of macros for the repeated vector forwarding patterns: |
| 23 | + |
| 24 | +- `SG_VARIANT_VEC_2IN_1OUT(NAME, IN1, IN2, OUT)` |
| 25 | +- `SG_VARIANT_VEC_1IN_1OUT(NAME, IN1, OUT)` |
| 26 | +- `SG_VARIANT_VEC_2IN_REFOUT(NAME, IN1, IN2, OUT)` |
| 27 | + |
| 28 | +These would cover the methods that forward to the same method on the active EOS in the variant. |
| 29 | + |
| 30 | +### 2. Optional scalar wrappers |
| 31 | + |
| 32 | +If further cleanup is desired, a second macro family could reduce the scalar `PortsOfCall::visit(...)` wrappers: |
| 33 | + |
| 34 | +- `SG_VARIANT_SCALAR_2IN_1OUT(NAME, A1, A2)` |
| 35 | +- `SG_VARIANT_SCALAR_1IN_1OUT(NAME, A1)` |
| 36 | +- `SG_VARIANT_SCALAR_2IN_REFOUT(NAME, A1, A2, OUT)` |
| 37 | + |
| 38 | +This scalar cleanup is optional. The highest-value, lowest-risk target is the vector section. |
| 39 | + |
| 40 | +## Best Targets For Vector Macros |
| 41 | + |
| 42 | +These methods appear to fit the macro pattern well: |
| 43 | + |
| 44 | +- `TemperatureFromDensityInternalEnergy` |
| 45 | +- `InternalEnergyFromDensityTemperature` |
| 46 | +- `PressureFromDensityTemperature` |
| 47 | +- `PressureFromDensityInternalEnergy` |
| 48 | +- `MinInternalEnergyFromDensity` |
| 49 | +- `EntropyFromDensityTemperature` |
| 50 | +- `EntropyFromDensityInternalEnergy` |
| 51 | +- `GibbsFreeEnergyFromDensityTemperature` |
| 52 | +- `GibbsFreeEnergyFromDensityInternalEnergy` |
| 53 | +- `SpecificHeatFromDensityTemperature` |
| 54 | +- `SpecificHeatFromDensityInternalEnergy` |
| 55 | +- `BulkModulusFromDensityTemperature` |
| 56 | +- `BulkModulusFromDensityInternalEnergy` |
| 57 | +- `GruneisenParamFromDensityTemperature` |
| 58 | +- `GruneisenParamFromDensityInternalEnergy` |
| 59 | +- `InternalEnergyFromDensityPressure` |
| 60 | + |
| 61 | +## Methods To Leave Handwritten |
| 62 | + |
| 63 | +These are less regular and should likely remain explicit: |
| 64 | + |
| 65 | +- `FillEos` |
| 66 | +- `ReferenceDensityTemperature` |
| 67 | +- `ValuesAtReferenceState` |
| 68 | +- `DensityEnergyFromPressureTemperature` |
| 69 | +- various introspection helpers |
| 70 | +- serialization helpers |
| 71 | + |
| 72 | +## Suggested Shape |
| 73 | + |
| 74 | +The vector section could collapse to a short list of macro invocations such as: |
| 75 | + |
| 76 | +```cpp |
| 77 | +SG_VARIANT_VEC_2IN_1OUT(TemperatureFromDensityInternalEnergy, rhos, sies, temperatures) |
| 78 | +SG_VARIANT_VEC_2IN_1OUT(InternalEnergyFromDensityTemperature, rhos, temperatures, sies) |
| 79 | +SG_VARIANT_VEC_2IN_1OUT(PressureFromDensityTemperature, rhos, temperatures, pressures) |
| 80 | +SG_VARIANT_VEC_2IN_1OUT(PressureFromDensityInternalEnergy, rhos, sies, pressures) |
| 81 | +SG_VARIANT_VEC_1IN_1OUT(MinInternalEnergyFromDensity, rhos, sies) |
| 82 | +SG_VARIANT_VEC_2IN_1OUT(EntropyFromDensityTemperature, rhos, temperatures, entropies) |
| 83 | +SG_VARIANT_VEC_2IN_1OUT(EntropyFromDensityInternalEnergy, rhos, sies, entropies) |
| 84 | +SG_VARIANT_VEC_2IN_1OUT(GibbsFreeEnergyFromDensityTemperature, rhos, temperatures, Gs) |
| 85 | +SG_VARIANT_VEC_2IN_1OUT(GibbsFreeEnergyFromDensityInternalEnergy, rhos, sies, Gs) |
| 86 | +SG_VARIANT_VEC_2IN_1OUT(SpecificHeatFromDensityTemperature, rhos, temperatures, cvs) |
| 87 | +SG_VARIANT_VEC_2IN_1OUT(SpecificHeatFromDensityInternalEnergy, rhos, sies, cvs) |
| 88 | +SG_VARIANT_VEC_2IN_1OUT(BulkModulusFromDensityTemperature, rhos, temperatures, bmods) |
| 89 | +SG_VARIANT_VEC_2IN_1OUT(BulkModulusFromDensityInternalEnergy, rhos, sies, bmods) |
| 90 | +SG_VARIANT_VEC_2IN_1OUT(GruneisenParamFromDensityTemperature, rhos, temperatures, gm1s) |
| 91 | +SG_VARIANT_VEC_2IN_1OUT(GruneisenParamFromDensityInternalEnergy, rhos, sies, gm1s) |
| 92 | +SG_VARIANT_VEC_2IN_REFOUT(InternalEnergyFromDensityPressure, rhos, Ps, sies) |
| 93 | +``` |
| 94 | +
|
| 95 | +## Important Constraint |
| 96 | +
|
| 97 | +The macros in `eos_variant.hpp` will be slightly more delicate than those in `eos_base.hpp`, because they use perfect forwarding through `PortsOfCall::visit` lambdas. That is still manageable, but it argues for a small, focused macro family rather than an overly generic one. |
| 98 | +
|
| 99 | +## Recommendation |
| 100 | +
|
| 101 | +Proceed with the vector macro refactor first. |
| 102 | +
|
| 103 | +It offers the best reduction in boilerplate with limited risk and preserves the existing overload set. If the result reads well, consider a second pass for the scalar `visit(...)` wrappers. |
0 commit comments