Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2002-2026 German Aerospace Center (DLR) and others.
4 : // This program and the accompanying materials are made available under the
5 : // terms of the Eclipse Public License 2.0 which is available at
6 : // https://www.eclipse.org/legal/epl-2.0/
7 : // This Source Code may also be made available under the following Secondary
8 : // Licenses when the conditions for such availability set forth in the Eclipse
9 : // Public License 2.0 are satisfied: GNU General Public License, version 2
10 : // or later which is available at
11 : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 : /****************************************************************************/
14 : /// @file RONet.h
15 : /// @author Daniel Krajzewicz
16 : /// @author Michael Behrisch
17 : /// @author Jakob Erdmann
18 : /// @author Yun-Pang Floetteroed
19 : /// @date Sept 2002
20 : ///
21 : // The router's network representation
22 : /****************************************************************************/
23 : #pragma once
24 : #include <config.h>
25 :
26 : #include <vector>
27 : #include <utils/common/MsgHandler.h>
28 : #include <utils/common/NamedObjectCont.h>
29 : #include <utils/distribution/RandomDistributor.h>
30 : #include <utils/vehicle/SUMOVehicleParameter.h>
31 : #include <utils/vehicle/SUMOVTypeParameter.h>
32 : #include "ROLane.h"
33 : #include "RORoutable.h"
34 : #include "RORouteDef.h"
35 :
36 : #ifdef HAVE_FOX
37 : #include <utils/foxtools/MFXWorkerThread.h>
38 : #endif
39 :
40 :
41 : // ===========================================================================
42 : // class declarations
43 : // ===========================================================================
44 : class ROEdge;
45 : class RONode;
46 : class ROPerson;
47 : class ROVehicle;
48 : class ROAbstractEdgeBuilder;
49 : class OptionsCont;
50 : class OutputDevice;
51 :
52 : typedef MapMatcher<ROEdge, ROLane, RONode> ROMapMatcher;
53 :
54 : // ===========================================================================
55 : // class definitions
56 : // ===========================================================================
57 : /**
58 : * @class RONet
59 : * @brief The router's network representation.
60 : *
61 : * A router network is responsible for watching loaded edges, nodes,!!!
62 : */
63 : class RONet {
64 : public:
65 :
66 : typedef std::map<const SUMOTime, std::vector<RORoutable*> > RoutablesMap;
67 : typedef std::map<const ROEdge*, RouterProhibition> Prohibitions;
68 : typedef std::map<const ROLane*, RouterProhibition> LaneProhibitions;
69 :
70 : /// @brief Constructor
71 : RONet();
72 :
73 :
74 : /** @brief Returns the pointer to the unique instance of RONet (singleton).
75 : * @return Pointer to the unique RONet-instance
76 : */
77 : static RONet* getInstance();
78 :
79 :
80 : /// @brief Destructor
81 : virtual ~RONet();
82 :
83 :
84 : /** @brief Adds a restriction for an edge type
85 : * @param[in] id The id of the type
86 : * @param[in] svc The vehicle class the restriction refers to
87 : * @param[in] speed The restricted speed
88 : */
89 : void addSpeedRestriction(const std::string& id, const SUMOVehicleClass svc, const double speed);
90 :
91 :
92 : /** @brief Returns the restrictions for an edge type
93 : * If no restrictions are present, 0 is returned.
94 : * @param[in] id The id of the type
95 : * @return The mapping of vehicle classes to maximum speeds
96 : */
97 : const std::map<SUMOVehicleClass, double>* getRestrictions(const std::string& id) const;
98 :
99 : bool hasSpeedRestrictions() const {
100 : return !mySpeedRestrictions.empty();
101 : }
102 :
103 : bool hasParamRestrictions() const {
104 830236 : return myHaveParamRestrictions;
105 : }
106 :
107 : void setParamRestrictions() {
108 34 : myHaveParamRestrictions = true;
109 : }
110 :
111 : /// @brief retriefe edge type specific routing preference
112 : double getPreference(const std::string& routingType, const SUMOVTypeParameter& pars) const;
113 :
114 : /// @brief add edge type specific routing preference
115 : void addPreference(const std::string& routingType, SUMOVehicleClass svc, double prio);
116 : /// @brief add edge type specific routing preference
117 : void addPreference(const std::string& routingType, std::string vType, double prio);
118 :
119 : /// @name Insertion and retrieval of graph parts
120 : //@{
121 :
122 : /* @brief Adds a read edge to the network
123 : *
124 : * If the edge is already known (another one with the same id exists),
125 : * an error is generated and given to msg-error-handler. The edge
126 : * is deleted in this case and false is returned.
127 : *
128 : * @param[in] edge The edge to add
129 : * @return Whether the edge was added (if not, it was deleted, too)
130 : */
131 : virtual bool addEdge(ROEdge* edge);
132 :
133 :
134 : /* @brief Adds a district and connecting edges to the network
135 : *
136 : * If the district is already known (another one with the same id exists),
137 : * an error is generated and given to msg-error-handler. The edges
138 : * are deleted in this case and false is returned.
139 : *
140 : * @param[in] id The district to add
141 : * @return Whether the district was added
142 : */
143 : bool addDistrict(const std::string id, ROEdge* source, ROEdge* sink);
144 :
145 :
146 : /* @brief Adds a district and connecting edges to the network
147 : *
148 : * If the district is already known (another one with the same id exists),
149 : * an error is generated and given to msg-error-handler. The edges
150 : * are deleted in this case and false is returned.
151 : *
152 : * @param[in] id The district to add
153 : * @return Whether the district was added
154 : */
155 : bool addDistrictEdge(const std::string tazID, const std::string edgeID, const bool isSource);
156 :
157 : /// @brief add a taz for every junction unless a taz with the same id already exists
158 : void addJunctionTaz(ROAbstractEdgeBuilder& eb);
159 :
160 : /// @brief add a taz for every junction unless a taz with the same id already exists
161 : void setBidiEdges(const std::map<ROEdge*, std::string>& bidiMap);
162 :
163 : /** @brief Retrieves all TAZ (districts) from the network
164 : *
165 : * @return The map of all districts
166 : */
167 : const std::map<std::string, std::pair<std::vector<std::string>, std::vector<std::string> > >& getDistricts() const {
168 104 : return myDistricts;
169 : }
170 :
171 : /** @brief Retrieves an edge from the network
172 : *
173 : * This is not very pretty, but necessary, though, as routes run
174 : * over instances, not over ids.
175 : *
176 : * @param[in] name The name of the edge to retrieve
177 : * @return The named edge if known, otherwise 0
178 : */
179 : ROEdge* getEdge(const std::string& name) const {
180 : return myEdges.get(name);
181 : }
182 :
183 :
184 : /** @brief Retrieves an edge from the network when the lane id is given
185 : *
186 : * @param[in] laneID The name of the lane to retrieve the edge for
187 : * @return The edge of the named lane if known, otherwise 0
188 : */
189 : ROEdge* getEdgeForLaneID(const std::string& laneID) const;
190 :
191 : /** @brief Retrieves a lane rom the network given its id
192 : *
193 : * @param[in] laneID The name of the lane to retrieve the edge for
194 : * @return The lane object
195 : */
196 : ROLane* getLane(const std::string& laneID) const;
197 :
198 : /* @brief Adds a read node to the network
199 : *
200 : * If the node is already known (another one with the same id exists),
201 : * an error is generated and given to msg-error-handler. The node
202 : * is deleted in this case
203 : *
204 : * @param[in] node The node to add
205 : */
206 : void addNode(RONode* node);
207 :
208 :
209 : /** @brief Retrieves an node from the network
210 : *
211 : * @param[in] name The name of the node to retrieve
212 : * @return The named node if known, otherwise 0
213 : * @todo Check whether a const pointer may be returned
214 : */
215 : RONode* getNode(const std::string& id) const {
216 : return myNodes.get(id);
217 : }
218 :
219 :
220 : /* @brief Adds a read stopping place (bus, train, container, parking) to the network
221 : *
222 : * If the place is already known (another one with the same id and category exists),
223 : * an error is generated and given to msg-error-handler. The stop
224 : * is deleted in this case
225 : *
226 : * @param[in] id The name of the stop to add
227 : * @param[in] category The type of stop
228 : * @param[in] stop The detailed stop description
229 : */
230 : void addStoppingPlace(const std::string& id, const SumoXMLTag category, SUMOVehicleParameter::Stop* stop);
231 :
232 : /** @brief Retrieves a stopping place from the network
233 : *
234 : * @param[in] id The name of the stop to retrieve
235 : * @param[in] category The type of stop
236 : * @return The named stop if known, otherwise 0
237 : */
238 2873 : const SUMOVehicleParameter::Stop* getStoppingPlace(const std::string& id, const SumoXMLTag category) const {
239 : if (myStoppingPlaces.count(category) > 0) {
240 : return myStoppingPlaces.find(category)->second.get(id);
241 : }
242 : return 0;
243 : }
244 :
245 : /// @brief return the name for the given stopping place id
246 : const std::string getStoppingPlaceName(const std::string& id) const;
247 :
248 : /// @brief return the element name for the given stopping place id
249 : const std::string getStoppingPlaceElement(const std::string& id) const;
250 : //@}
251 :
252 :
253 :
254 : /// @name Insertion and retrieval of vehicle types, vehicles, routes, and route definitions
255 : //@{
256 :
257 : /** @brief Checks whether the vehicle type (distribution) may be added
258 : *
259 : * This method checks also whether the default type may still be replaced
260 : * @param[in] id The id of the vehicle type (distribution) to add
261 : * @return Whether the type (distribution) may be added
262 : */
263 : bool checkVType(const std::string& id);
264 :
265 :
266 : /** @brief Adds a read vehicle type definition to the network
267 : *
268 : * If the vehicle type definition is already known (another one with
269 : * the same id exists), false is returned, and the vehicle type
270 : * is deleted.
271 : *
272 : * @param[in] def The vehicle type to add
273 : * @return Whether the vehicle type could be added
274 : */
275 : virtual bool addVehicleType(SUMOVTypeParameter* type);
276 :
277 :
278 : /** @brief Adds a vehicle type distribution
279 : *
280 : * If another vehicle type (or distribution) with the same id exists, false is returned.
281 : * Otherwise, the vehicle type distribution is added to the internal vehicle type distribution
282 : * container "myVTypeDistDict".
283 : *
284 : * This control get responsible for deletion of the added vehicle
285 : * type distribution.
286 : *
287 : * @param[in] id The id of the distribution to add
288 : * @param[in] vehTypeDistribution The vehicle type distribution to add
289 : * @return Whether the vehicle type could be added
290 : */
291 : bool addVTypeDistribution(const std::string& id, RandomDistributor<SUMOVTypeParameter*>* vehTypeDistribution);
292 :
293 :
294 : /** @brief Retrieves the named vehicle type distribution
295 : *
296 : * If the named vehicle type distribution was not added to the net before
297 : * nullptr is returned
298 : *
299 : * @param[in] id The id of the vehicle type distribution to return
300 : * @return The named vehicle type distribution
301 : */
302 : const RandomDistributor<SUMOVTypeParameter*>* getVTypeDistribution(const std::string& id) {
303 : const auto it = myVTypeDistDict.find(id);
304 192355 : return it != myVTypeDistDict.end() ? it ->second : nullptr;
305 : }
306 :
307 :
308 : /** @brief Retrieves the named vehicle type
309 : *
310 : * If the name is "" the default type is returned.
311 : * If the named vehicle type (or typeDistribution) was not added to the net before
312 : * nullptr is returned
313 : *
314 : * @param[in] id The id of the vehicle type to return
315 : * @return The named vehicle type
316 : */
317 : SUMOVTypeParameter* getVehicleTypeSecure(const std::string& id);
318 :
319 :
320 : /* @brief Adds a route definition to the network
321 : *
322 : * If the route definition is already known (another one with
323 : * the same id exists), false is returned, but the route definition
324 : * is not deleted.
325 : *
326 : * @param[in] def The route definition to add
327 : * @return Whether the route definition could be added
328 : * @todo Rename myRoutes to myRouteDefinitions
329 : */
330 : bool addRouteDef(RORouteDef* def);
331 :
332 :
333 : /** @brief Returns the named route definition
334 : *
335 : * @param[in] name The name of the route definition to retrieve
336 : * @return The named route definition if known, otherwise 0
337 : * @todo Check whether a const pointer may be returned
338 : * @todo Rename myRoutes to myRouteDefinitions
339 : */
340 : RORouteDef* getRouteDef(const std::string& name) const {
341 : return myRoutes.get(name);
342 : }
343 :
344 :
345 : /* @brief Adds a vehicle to the network
346 : *
347 : * If the vehicle is already known (another one with the same id
348 : * exists), false is returned, but the vehicle is not deleted.
349 : *
350 : * Otherwise, the number of loaded routes ("myReadRouteNo") is increased.
351 : *
352 : * @param[in] id The id of the vehicle to add
353 : * @param[in] veh The vehicle to add
354 : * @return Whether the vehicle could be added
355 : */
356 : virtual bool addVehicle(const std::string& id, ROVehicle* veh);
357 :
358 : /// @brief returns whether a vehicle with the given id was already loaded
359 : bool knowsVehicle(const std::string& id) const;
360 :
361 : /// @brief returns departure time for the given vehicle id
362 : SUMOTime getDeparture(const std::string& vehID) const;
363 :
364 : /* @brief Adds a flow of vehicles to the network
365 : *
366 : * If the flow is already known (another one with the same id
367 : * exists), false is returned, but the vehicle parameter are not deleted.
368 : *
369 : * Otherwise, the number of loaded routes ("myReadRouteNo") is increased.
370 : *
371 : * @param[in] flow The parameter of the flow to add
372 : * @return Whether the flow could be added
373 : */
374 : bool addFlow(SUMOVehicleParameter* flow, const bool randomize);
375 :
376 :
377 : /* @brief Adds a person to the network
378 : *
379 : * @param[in] person The person to add
380 : */
381 : bool addPerson(ROPerson* person);
382 :
383 :
384 : /* @brief Adds a container to the network
385 : *
386 : * @param[in] depart The departure time of the container
387 : * @param[in] desc The xml description of the container
388 : */
389 : void addContainer(const SUMOTime depart, const std::string desc);
390 : // @}
391 :
392 :
393 : /// @name Processing stored vehicle definitions
394 : //@{
395 :
396 : /** @brief Computes routes described by their definitions and saves them
397 : *
398 : * As long as a vehicle with a departure time smaller than the given
399 : * exists, its route is computed and it is written and removed from
400 : * the internal container.
401 : *
402 : * @param[in] options The options used during this process
403 : * @param[in] provider The router provider for routes computation
404 : * @param[in] time The time until which route definitions shall be processed
405 : * @return The last seen departure time>=time
406 : */
407 : SUMOTime saveAndRemoveRoutesUntil(OptionsCont& options,
408 : const RORouterProvider& provider, SUMOTime time);
409 :
410 :
411 : /// Returns the information whether further vehicles, persons or containers are stored
412 : bool furtherStored();
413 : //@}
414 :
415 :
416 : /** @brief Opens the output for computed routes
417 : *
418 : * If one of the file outputs can not be build, an IOError is thrown.
419 : *
420 : * @param[in] options The options to be asked for "output-file", "alternatives-output" and "vtype-output"
421 : */
422 : void openOutput(const OptionsCont& options);
423 :
424 :
425 : /** @brief Writes the intermodal network and weights if requested
426 : *
427 : * If one of the file outputs can not be build, an IOError is thrown.
428 : *
429 : * @param[in] options The options to be asked for "intermodal-network-output" and "intermodal-weight-output"
430 : */
431 : void writeIntermodal(const OptionsCont& options, ROIntermodalRouter& router) const;
432 :
433 :
434 : /** @brief closes the file output for computed routes and deletes associated threads if necessary */
435 : void cleanup();
436 :
437 :
438 : /// Returns the total number of edges the network contains including internal edges
439 : int getEdgeNumber() const;
440 :
441 : /// Returns the number of internal edges the network contains
442 : int getInternalEdgeNumber() const;
443 :
444 : const NamedObjectCont<ROEdge*>& getEdgeMap() const {
445 : return myEdges;
446 : }
447 :
448 : static void adaptIntermodalRouter(ROIntermodalRouter& router);
449 :
450 : bool hasPermissions() const;
451 :
452 : void setPermissionsFound();
453 :
454 : /// @brief return whether the network contains bidirectional rail edges
455 : bool hasBidiEdges() const {
456 2694 : return myHasBidiEdges;
457 : }
458 :
459 : /// @brief whether efforts were loaded from file
460 : bool hasLoadedEffort() const;
461 :
462 : double getMaxTraveltime() const {
463 281018 : return myMaxTraveltime;
464 : }
465 :
466 : const Prohibitions& getProhibitions() const {
467 12 : return myProhibitions;
468 : }
469 :
470 : void updateLaneProhibitions(SUMOTime begin);
471 :
472 : void addProhibition(const ROEdge* edge, const RouterProhibition& prohibition);
473 : void addLaneProhibition(const ROLane* lane, const RouterProhibition& prohibition);
474 :
475 : OutputDevice* getRouteOutput(const bool alternative = false) {
476 : if (alternative) {
477 : return myRouteAlternativesOutput;
478 : }
479 73 : return myRoutesOutput;
480 : }
481 :
482 : #ifdef HAVE_FOX
483 : MFXWorkerThread::Pool& getThreadPool() {
484 163 : return myThreadPool;
485 : }
486 :
487 : class WorkerThread : public MFXWorkerThread, public RORouterProvider {
488 : public:
489 53 : WorkerThread(MFXWorkerThread::Pool& pool,
490 : const RORouterProvider& original)
491 53 : : MFXWorkerThread(pool), RORouterProvider(original) {}
492 106 : virtual ~WorkerThread() {
493 53 : stop();
494 106 : }
495 : };
496 :
497 : class BulkmodeTask : public MFXWorkerThread::Task {
498 : public:
499 84 : BulkmodeTask(const bool value) : myValue(value) {}
500 84 : void run(MFXWorkerThread* context) {
501 84 : static_cast<WorkerThread*>(context)->setBulkMode(myValue);
502 84 : }
503 : private:
504 : const bool myValue;
505 : private:
506 : /// @brief Invalidated assignment operator.
507 : BulkmodeTask& operator=(const BulkmodeTask&);
508 : };
509 : #endif
510 :
511 :
512 : private:
513 : void checkFlows(SUMOTime time, MsgHandler* errorHandler);
514 :
515 : void createBulkRouteRequests(const RORouterProvider& provider, const SUMOTime time, const bool removeLoops);
516 :
517 : private:
518 : /// @brief Unique instance of RONet
519 : static RONet* myInstance;
520 :
521 : /// @brief Known vehicle ids and their departure
522 : std::map<std::string, SUMOTime> myVehIDs;
523 :
524 : /// @brief Known person ids
525 : std::set<std::string> myPersonIDs;
526 :
527 : /// @brief Known nodes
528 : NamedObjectCont<RONode*> myNodes;
529 :
530 : /// @brief Known edges
531 : NamedObjectCont<ROEdge*> myEdges;
532 :
533 : /// @brief Known bus / train / container stops and parking areas
534 : std::map<SumoXMLTag, NamedObjectCont<SUMOVehicleParameter::Stop*> > myStoppingPlaces;
535 :
536 : /// @brief Known vehicle types
537 : NamedObjectCont<SUMOVTypeParameter*> myVehicleTypes;
538 :
539 : /// @brief Vehicle type distribution dictionary type
540 : typedef std::map< std::string, RandomDistributor<SUMOVTypeParameter*>* > VTypeDistDictType;
541 : /// @brief A distribution of vehicle types (probability->vehicle type)
542 : VTypeDistDictType myVTypeDistDict;
543 :
544 : /// @brief Whether the default vehicle type was already used or can still be replaced
545 : bool myDefaultVTypeMayBeDeleted;
546 :
547 : /// @brief Whether the default pedestrian type was already used or can still be replaced
548 : bool myDefaultPedTypeMayBeDeleted;
549 :
550 : /// @brief Whether the default bicycle type was already used or can still be replaced
551 : bool myDefaultBikeTypeMayBeDeleted;
552 :
553 : /// @brief Whether the default taxi type was already used or can still be replaced
554 : bool myDefaultTaxiTypeMayBeDeleted;
555 :
556 : /// @brief Whether the default rail type was already used or can still be replaced
557 : bool myDefaultRailTypeMayBeDeleted;
558 :
559 : /// @brief Known routes
560 : NamedObjectCont<RORouteDef*> myRoutes;
561 :
562 : /// @brief Known routables
563 : RoutablesMap myRoutables;
564 :
565 : /// @brief Known flows
566 : NamedObjectCont<SUMOVehicleParameter*> myFlows;
567 :
568 : /// @brief whether any flows are still active
569 : bool myHaveActiveFlows;
570 :
571 : /// @brief Known containers
572 : typedef std::multimap<const SUMOTime, const std::string> ContainerMap;
573 : ContainerMap myContainers;
574 :
575 : /// @brief vehicles to keep for public transport routing
576 : std::vector<const RORoutable*> myPTVehicles;
577 :
578 : /// @brief Departure times for randomized flows
579 : std::map<std::string, std::vector<SUMOTime> > myDepartures;
580 :
581 : /// @brief traffic assignment zones with sources and sinks
582 : std::map<std::string, std::pair<std::vector<std::string>, std::vector<std::string> > > myDistricts;
583 :
584 : /// @brief The file to write the computed routes into
585 : OutputDevice* myRoutesOutput;
586 :
587 : /// @brief The file to write the computed route alternatives into
588 : OutputDevice* myRouteAlternativesOutput;
589 :
590 : /// @brief The file to write the vehicle types into
591 : OutputDevice* myTypesOutput;
592 :
593 : /// @brief The number of read routes
594 : int myReadRouteNo;
595 :
596 : /// @brief The number of discarded routes
597 : int myDiscardedRouteNo;
598 :
599 : /// @brief The number of written routes
600 : int myWrittenRouteNo;
601 :
602 : /// @brief Whether the network contains edges which not all vehicles may pass
603 : bool myHavePermissions;
604 :
605 : /// @brief The vehicle class specific speed restrictions
606 : std::map<std::string, std::map<SUMOVehicleClass, double> > mySpeedRestrictions;
607 :
608 : /// @brief whether parameter-based access restrictions are configured
609 : bool myHaveParamRestrictions;
610 :
611 : /// @brief Preferences for routing
612 : std::map<SUMOVehicleClass, std::map<std::string, double> > myVClassPreferences;
613 : std::map<std::string, std::map<std::string, double> > myVTypePreferences;
614 :
615 : /// @brief The number of internal edges in the dictionary
616 : int myNumInternalEdges;
617 :
618 : /// @brief handler for ignorable error messages
619 : MsgHandler* myErrorHandler;
620 :
621 : /// @brief whether to keep the vtype distribution in output
622 : const bool myKeepVTypeDist;
623 :
624 : /// @brief whether to calculate routes for public transport
625 : const bool myDoPTRouting;
626 :
627 : /// @brief whether to preserve flows
628 : const bool myKeepFlows;
629 :
630 : /// @brief whether the network contains bidirectional railway edges
631 : bool myHasBidiEdges;
632 :
633 : /// @brief the maximum traveltime beyond which routing is considered a failure
634 : const double myMaxTraveltime;
635 :
636 : /// @brief temporary edge closing (rerouters)
637 : Prohibitions myProhibitions;
638 : /// @brief temporary lane closing (rerouters)
639 : LaneProhibitions myLaneProhibitions;
640 : std::map<double, std::set<const ROLane*> > myLaneProhibitionTimes;
641 :
642 : #ifdef HAVE_FOX
643 : private:
644 : class RoutingTask : public MFXWorkerThread::Task {
645 : public:
646 : RoutingTask(RORoutable* v, const bool removeLoops, MsgHandler* errorHandler)
647 923 : : myRoutable(v), myRemoveLoops(removeLoops), myErrorHandler(errorHandler) {}
648 : void run(MFXWorkerThread* context);
649 : private:
650 : RORoutable* const myRoutable;
651 : const bool myRemoveLoops;
652 : MsgHandler* const myErrorHandler;
653 : private:
654 : /// @brief Invalidated assignment operator.
655 : RoutingTask& operator=(const RoutingTask&);
656 : };
657 :
658 :
659 : private:
660 : /// @brief for multi threaded routing
661 : MFXWorkerThread::Pool myThreadPool;
662 : #endif
663 :
664 : private:
665 : /// @brief Invalidated copy constructor
666 : RONet(const RONet& src);
667 :
668 : /// @brief Invalidated assignment operator
669 : RONet& operator=(const RONet& src);
670 :
671 : };
|