#pragma once
#include <config.h>
template<class E, class V>
class ReversedEdge {
public:
typedef std::vector<std::pair<const ReversedEdge<E, V>*, const ReversedEdge<E, V>*> > ConstEdgePairVector;
ReversedEdge(const E* orig) : myOriginal(orig) {
}
void init() {
if (!myOriginal->isInternal()) {
for (const auto& viaPair : myOriginal->getViaSuccessors()) {
const ReversedEdge<E, V>* revSource = viaPair.first->getReversedRoutingEdge();
const E* via = viaPair.second;
const ReversedEdge<E, V>* preVia = nullptr;
while (via != nullptr && via->isInternal()) {
via->getReversedRoutingEdge()->myViaSuccessors.push_back(std::make_pair(this, preVia));
preVia = via->getReversedRoutingEdge();
via = via->getViaSuccessors().front().second;
}
revSource->myViaSuccessors.push_back(std::make_pair(this, preVia));
}
}
}
const E* getOriginalEdge() const {
return myOriginal;
}
int getNumericalID() const {
return myOriginal->getNumericalID();
}
const std::string& getID() const {
return myOriginal->getID();
}
double getLength() const {
return myOriginal->getLength();
}
const ReversedEdge* getBidiEdge() const {
return myOriginal->getBidiEdge()->getReversedRoutingEdge();
}
bool isInternal() const {
return myOriginal->isInternal();
}
inline bool prohibits(const V* const vehicle) const {
return myOriginal->prohibits(vehicle);
}
inline bool restricts(const V* const vehicle) const {
return myOriginal->restricts(vehicle);
}
static inline double getTravelTimeStatic(const ReversedEdge<E, V>* const edge, const V* const veh, double time) {
return edge->myOriginal->getTravelTime(veh, time);
}
const ConstEdgePairVector& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING, bool ignoreTransientPermissions = false) const {
UNUSED_PARAMETER(ignoreTransientPermissions);
if (vClass == SVC_IGNORING || myOriginal->isTazConnector()) {
return myViaSuccessors;
}
#ifdef HAVE_FOX
FXMutexLock lock(mySuccessorMutex);
#endif
auto i = myClassesViaSuccessorMap.find(vClass);
if (i != myClassesViaSuccessorMap.end()) {
return i->second;
}
ConstEdgePairVector& result = myClassesViaSuccessorMap[vClass];
for (const auto& viaPair : myViaSuccessors) {
if (viaPair.first->myOriginal->isTazConnector() || viaPair.first->myOriginal->isConnectedTo(*myOriginal, vClass)) {
result.push_back(viaPair);
}
}
return result;
}
private:
const E* const myOriginal;
mutable std::map<SUMOVehicleClass, ConstEdgePairVector> myClassesViaSuccessorMap;
mutable ConstEdgePairVector myViaSuccessors;
#ifdef HAVE_FOX
mutable FXMutex mySuccessorMutex;
#endif
};