FLAMEGPU2
FLAMEGPU2 copied to clipboard
RunPlan / RunPlanVectory operator+ and operator+=
Currently RunPlan
and RunPlanVector
have several operator+
and operator+=
operator overloads, which combine one or more plans into a single RunPlanVector.
I.e. (for illustration only)
flamegpu::RunPlanVector AB(model, 2); // Contains 2 plans, [A, B]
flamegpu::RunPlanVector CD(model, 2); // Contains 2 plans, [C, D]
flamegpu::RunPlan E(model); // A single Plan, E
// vector + vector
flamegpu::RunPlan ABCD = AB + CD; // contains [A, B, C, D]
// Vector += vector
flamegpu::RunPlan ABCD(model, 0);
ABCD += AB;
ABCD += CD; // Contains [A, B, C, D]
// Vector + Plan
flamegpu::RunPlanVector ABE = AB + E; // Contains [A, B, E]
// Vector += Plan
flamegpu::RunPlanVector ABE(model, 0);
ABE += AB;
ABE += E; // Contains [A, B, E]
However, as a vector is used internally, this is implemented as push_back
only, which leads to potentially unexpected orders when operator+
I.e. (for illustration only)
flamegpu::RunPlanVector AB(model, 2); // Contains 2 plans, [A, B]
flamegpu::RunPlanVector CD(model, 2); // Contains 2 plans, [C, D]
flamegpu::RunPlan E(model); // A single Plan, E
// vector + vector
flamegpu::RunPlan CDAB = CD + AB; // contains [A, B, C, D] - i.e. it was an append not a prepend
// Vector += vector
flamegpu::RunPlan CDAB(model, 0);
CDAB += AB;
CDAB += CD; // Contains [A, B, C, D], not the expected/intended [C, D, A, B]
// Vector + Plan
flamegpu::RunPlanVector EAB = E + AB; // Contains [A, B, E] - not the intended/expected [E, A, B]
// Vector += Plan
flamegpu::RunPlanVector EAB(model, 0);
ABE += E;
ABE += AB; // Contains [A, B, E] as expected. Cannot directly E+= AB would however not make sense / be possible.
We could define/implement operator+(lhs, rhs)
outside of the classes (and/or friend it in) to enable append / prepend behaviour, but this doesn't make sense for operator+=
, nor versions which return a reference like the current implementations.
Given this is essentially a thin wrapper around std::vector
, instead we could just implement push_back
rather than provide these operator overloads. This might not be as user-friendly, but also avoids operator+ leading to confusion of order.
Or as another alternative, we could move to an underlying implementation other than Vector, which supports high performance prepend/push_front operations (std::list
?). There might be other consequences of this, but I think this would still suit the same purpose, and grand-scheme the performance of run plan construction will be negligible compared to the simulations themselves.
Any of these will be a breaking change, so sooner rather than later is better.
These are also not being wrapped correctly by swig currently, so this should be addressed at the same time.