@@ -206,15 +206,26 @@ void ContainerBasePrivate::copyState(Interface::iterator external, const Interfa
206206void ContainerBasePrivate::liftSolution (const SolutionBasePtr& solution, const InterfaceState* internal_from,
207207 const InterfaceState* internal_to, InterfaceState* new_from,
208208 InterfaceState* new_to) {
209- const bool create_from{ requiredInterface ().testFlag (WRITES_PREV_END) };
210- const bool create_to{ requiredInterface ().testFlag (WRITES_NEXT_START) };
209+ // NOLINTNEXTLINE(readability-identifier-naming)
210+ auto findExternal = [this ](InterfaceState* replacement, const InterfaceState* internal) -> const InterfaceState* {
211+ auto it = internalToExternalMap ().find (internal);
212+ if (it != internalToExternalMap ().end ()) {
213+ return &*it->second ;
214+ }
215+
216+ // if replacement has been created before it was returned above already
217+ if (replacement)
218+ return replacement;
219+
220+ return nullptr ;
221+ };
211222
212223 // external states, nullptr if they don't exist yet
213- const InterfaceState* external_from{ create_from ? new_from : internalToExternalMap (). at ( internal_from) };
214- const InterfaceState* external_to{ create_to ? new_to : internalToExternalMap (). at ( internal_to) };
224+ const InterfaceState* external_from{ findExternal ( new_from, internal_from) };
225+ const InterfaceState* external_to{ findExternal ( new_to, internal_to) };
215226
216227 // computeCost
217- // we can pass intern_ {from/to} here because in this case the lifted states that might be created later
228+ // we can pass internal_ {from/to} here because in this case the lifted states that might be created later
218229 // are equivalent up to the connected Solutions (which are not relevant for CostTerms)
219230 computeCost (external_from ? *external_from : *internal_from, external_to ? *external_to : *internal_to, *solution);
220231
@@ -223,21 +234,31 @@ void ContainerBasePrivate::liftSolution(const SolutionBasePtr& solution, const I
223234 return ;
224235 }
225236
226- auto create_state = [this ](const InterfaceState& internal, InterfaceState* new_external) {
237+ // create unstored states in stage-internal storage
238+
239+ // NOLINTNEXTLINE(readability-identifier-naming)
240+ auto createState = [this ](const InterfaceState& internal, InterfaceState* new_external) {
227241 InterfaceState* external{ storeState (new_external ? std::move (*new_external) : InterfaceState{ internal }) };
228242 internalToExternalMap ().insert (std::make_pair (&internal, external));
229243 return external;
230244 };
231245
232- if (create_from)
233- external_from = create_state (*internal_from, new_from);
234- if (create_to)
235- external_to = create_state (*internal_to, new_to);
246+ const bool create_from{ new_from != nullptr || external_from == nullptr };
247+ const bool create_to{ new_to != nullptr || external_to == nullptr };
248+
249+ if (create_from) {
250+ assert (requiredInterface ().testFlag (WRITES_PREV_END));
251+ external_from = createState (*internal_from, new_from);
252+ }
253+ if (create_to) {
254+ assert (requiredInterface ().testFlag (WRITES_NEXT_START));
255+ external_to = createState (*internal_to, new_to);
256+ }
236257
237258 assert (external_from);
238259 assert (external_to);
239260
240- // connect solution to states
261+ // connect solution to stored states
241262 solution->setStartState (*external_from);
242263 solution->setEndState (*external_to);
243264
0 commit comments