Eclipse SUMO - Simulation of Urban MObility
SUMOVehicleClass.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2020 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 /****************************************************************************/
22 // Definitions of SUMO vehicle classes and helper functions
23 /****************************************************************************/
24 #include <config.h>
25 
26 #include <string>
27 #include <map>
28 #include "SUMOVehicleClass.h"
30 #include <utils/common/ToString.h>
35 
36 
37 // ===========================================================================
38 // static members
39 // ===========================================================================
40 
42  {"ignoring", SVC_IGNORING},
43  {"private", SVC_PRIVATE},
44  {"public_emergency", SVC_EMERGENCY}, // !!! deprecated
45  {"emergency", SVC_EMERGENCY},
46  {"public_authority", SVC_AUTHORITY}, // !!! deprecated
47  {"authority", SVC_AUTHORITY},
48  {"public_army", SVC_ARMY}, // !!! deprecated
49  {"army", SVC_ARMY},
50  {"vip", SVC_VIP},
51  {"passenger", SVC_PASSENGER},
52  {"hov", SVC_HOV},
53  {"taxi", SVC_TAXI},
54  {"public_transport", SVC_BUS}, // !!! deprecated
55  {"bus", SVC_BUS},
56  {"coach", SVC_COACH},
57  {"delivery", SVC_DELIVERY},
58  {"transport", SVC_TRUCK},
59  {"truck", SVC_TRUCK},
60  {"trailer", SVC_TRAILER},
61  {"lightrail", SVC_TRAM}, // !!! deprecated
62  {"tram", SVC_TRAM},
63  {"cityrail", SVC_RAIL_URBAN}, // !!! deprecated
64  {"rail_urban", SVC_RAIL_URBAN},
65  {"rail_slow", SVC_RAIL}, // !!! deprecated
66  {"rail", SVC_RAIL},
67  {"rail_fast", SVC_RAIL_FAST},
68  {"rail_electric", SVC_RAIL_ELECTRIC},
69  {"motorcycle", SVC_MOTORCYCLE},
70  {"moped", SVC_MOPED},
71  {"bicycle", SVC_BICYCLE},
72  {"pedestrian", SVC_PEDESTRIAN},
73  {"evehicle", SVC_E_VEHICLE},
74  {"ship", SVC_SHIP},
75  {"custom1", SVC_CUSTOM1},
76  {"custom2", SVC_CUSTOM2}
77 };
78 
81 
82 
83 std::set<std::string> deprecatedVehicleClassesSeen;
84 
85 
87  {"pedestrian", SVS_PEDESTRIAN},
88  {"bicycle", SVS_BICYCLE},
89  {"moped", SVS_MOPED},
90  {"motorcycle", SVS_MOTORCYCLE},
91  {"passenger", SVS_PASSENGER},
92  {"passenger/sedan", SVS_PASSENGER_SEDAN},
93  {"passenger/hatchback", SVS_PASSENGER_HATCHBACK},
94  {"passenger/wagon", SVS_PASSENGER_WAGON},
95  {"passenger/van", SVS_PASSENGER_VAN},
96  {"delivery", SVS_DELIVERY},
97  {"transport", SVS_TRUCK}, // !!! deprecated
98  {"truck", SVS_TRUCK},
99  {"transport/semitrailer", SVS_TRUCK_SEMITRAILER}, // !!! deprecated
100  {"truck/semitrailer", SVS_TRUCK_SEMITRAILER},
101  {"transport/trailer", SVS_TRUCK_1TRAILER}, // !!! deprecated
102  {"truck/trailer", SVS_TRUCK_1TRAILER},
103  {"bus/city", SVS_BUS}, // !!! deprecated
104  {"bus", SVS_BUS},
105  {"bus/overland", SVS_BUS_COACH}, // !!! deprecated
106  {"bus/coach", SVS_BUS_COACH},
107  {"bus/flexible", SVS_BUS_FLEXIBLE},
108  {"bus/trolley", SVS_BUS_TROLLEY},
109  {"rail/slow", SVS_RAIL}, // !!! deprecated
110  {"rail/fast", SVS_RAIL}, // !!! deprecated
111  {"rail", SVS_RAIL},
112  {"rail/light", SVS_RAIL_CAR}, // !!! deprecated
113  {"rail/city", SVS_RAIL_CAR}, // !!! deprecated
114  {"rail/railcar", SVS_RAIL_CAR},
115  {"rail/cargo", SVS_RAIL_CARGO},
116  {"evehicle", SVS_E_VEHICLE},
117  {"ant", SVS_ANT},
118  {"ship", SVS_SHIP},
119  {"emergency", SVS_EMERGENCY},
120  {"firebrigade", SVS_FIREBRIGADE},
121  {"police", SVS_POLICE},
122  {"rickshaw", SVS_RICKSHAW },
123  {"", SVS_UNKNOWN}
124 };
125 
126 
129 
130 // ===========================================================================
131 // static values used for cached
132 // ===========================================================================
133 
134 static std::map<int, std::vector<std::string> > vehicleClassNamesListCached;
135 static std::map<std::string, SVCPermissions> parseVehicleClassesCached;
136 static std::map<SVCPermissions, std::string> getVehicleClassNamesCached;
137 static std::string vehicleClassNameAll = "all";
138 
139 // ===========================================================================
140 // additional constants
141 // ===========================================================================
142 
144 
145 const SVCPermissions SVCAll = 2 * (int)SUMOVehicleClass_MAX - 1; // all relevant bits set to 1
146 
148 
149 const std::string DEFAULT_VTYPE_ID("DEFAULT_VEHTYPE");
150 
151 const std::string DEFAULT_PEDTYPE_ID("DEFAULT_PEDTYPE");
152 
153 const std::string DEFAULT_BIKETYPE_ID("DEFAULT_BIKETYPE");
154 
155 const std::string DEFAULT_CONTAINERTYPE_ID("DEFAULT_CONTAINERTYPE");
156 
157 const std::string DEFAULT_TAXITYPE_ID("DEFAULT_TAXITYPE");
158 
159 const double DEFAULT_VEH_PROB(1.);
160 
161 const double DEFAULT_PEDESTRIAN_SPEED(5. / 3.6);
162 
163 const double DEFAULT_CONTAINER_TRANSHIP_SPEED(5. / 3.6);
164 
165 // ===========================================================================
166 // method definitions
167 // ===========================================================================
168 // ------------ Conversion of SUMOVehicleClass
169 
170 const std::string&
171 getVehicleClassNames(SVCPermissions permissions, bool expand) {
172  if (permissions == SVCAll && !expand) {
173  return vehicleClassNameAll;
174  }
175  // check if previously was cached
176  if (getVehicleClassNamesCached.count(permissions) == 0) {
177  getVehicleClassNamesCached[permissions] = joinToString(getVehicleClassNamesList(permissions), ' ');
178  }
179  return getVehicleClassNamesCached.at(permissions);
180 }
181 
182 
183 const std::vector<std::string>&
185  // first check if it's cached
186  if (vehicleClassNamesListCached.count(permissions) == 0) {
187  const std::vector<std::string> classNames = SumoVehicleClassStrings.getStrings();
188  std::vector<std::string> result;
189  for (std::vector<std::string>::const_iterator it = classNames.begin(); it != classNames.end(); it++) {
190  const int svc = (int)SumoVehicleClassStrings.get(*it);
191  if ((svc & permissions) == svc && svc != SVC_IGNORING) {
192  result.push_back(*it);
193  }
194  }
195  // add it into vehicleClassNamesListCached
196  vehicleClassNamesListCached[permissions] = result;
197  }
198  return vehicleClassNamesListCached.at(permissions);
199 }
200 
201 
203 getVehicleClassID(const std::string& name) {
204  if (SumoVehicleClassStrings.hasString(name)) {
205  return SumoVehicleClassStrings.get(name);
206  }
207  throw InvalidArgument("Unknown vehicle class '" + name + "'.");
208 }
209 
210 
211 int
212 getVehicleClassCompoundID(const std::string& name) {
213  int ret = SVC_IGNORING;
214  const std::vector<std::string> names = SumoVehicleClassStrings.getStrings();
215  for (std::vector<std::string>::const_iterator it = names.begin(); it != names.end(); it++) {
216  if (name.find(*it) != std::string::npos) {
217  ret = ret | (int) SumoVehicleClassStrings.get(*it);
218  }
219  }
220  return ret;
221 }
222 
223 
225 parseVehicleClasses(const std::string& allowedS) {
226  if (allowedS == "all") {
227  return SVCAll;
228  }
229  // check if allowedS was previously cached
230  if (parseVehicleClassesCached.count(allowedS) == 0) {
231  SVCPermissions result = 0;
232  StringTokenizer sta(allowedS, " ");
233  while (sta.hasNext()) {
234  const std::string s = sta.next();
235  if (!SumoVehicleClassStrings.hasString(s)) {
236  WRITE_ERROR("Unknown vehicle class '" + s + "' encountered.");
237  } else {
238  const SUMOVehicleClass vc = getVehicleClassID(s);
239  const std::string& realName = SumoVehicleClassStrings.getString(vc);
240  if (realName != s) {
242  }
243  result |= vc;
244  }
245  }
246  // save parsed vehicle class cached
247  parseVehicleClassesCached[allowedS] = result;
248  }
249  return parseVehicleClassesCached.at(allowedS);
250 }
251 
252 
253 bool
254 canParseVehicleClasses(const std::string& classes) {
255  if (classes == "all") {
256  return true;
257  }
258  // check if was previously cached
259  if (parseVehicleClassesCached.count(classes) != 0) {
260  return true;
261  }
262  StringTokenizer sta(classes, " ");
263  while (sta.hasNext()) {
264  if (!SumoVehicleClassStrings.hasString(sta.next())) {
265  return false;
266  }
267  }
268  return true;
269 }
270 
271 
273 parseVehicleClasses(const std::string& allowedS, const std::string& disallowedS, double networkVersion) {
274  if (allowedS.size() == 0 && disallowedS.size() == 0) {
275  return SVCAll;
276  } else if (allowedS.size() > 0 && disallowedS.size() > 0) {
277  WRITE_WARNING("SVCPermissions must be specified either via 'allow' or 'disallow'. Ignoring 'disallow'");
278  return parseVehicleClasses(allowedS);
279  } else if (allowedS.size() > 0) {
280  return parseVehicleClasses(allowedS);
281  } else {
282  return invertPermissions(parseVehicleClasses(disallowedS) | (networkVersion < 1.3 ? SVC_RAIL_FAST : 0));
283  }
284 }
285 
286 
289  return SVCAll & ~permissions;
290 }
291 
292 
294 parseVehicleClasses(const std::vector<std::string>& allowedS) {
295  SVCPermissions result = 0;
296  if (std::find(allowedS.begin(), allowedS.end(), "all") != allowedS.end()) {
297  return SVCAll;
298  }
299  for (std::vector<std::string>::const_iterator i = allowedS.begin(); i != allowedS.end(); ++i) {
300  const SUMOVehicleClass vc = getVehicleClassID(*i);
301  const std::string& realName = SumoVehicleClassStrings.getString(vc);
302  if (realName != *i) {
303  WRITE_WARNING("The vehicle class '" + (*i) + "' is deprecated, use '" + realName + "' instead.");
304  }
305  result |= getVehicleClassID(*i);
306  }
307  return result;
308 }
309 
310 
311 void
313  if (permissions == SVCAll) {
314  return;
315  } else if (permissions == 0) {
316  into.writeAttr(SUMO_ATTR_DISALLOW, "all");
317  return;
318  } else {
319  int num_allowed = 0;
320  for (int mask = 1; mask <= SUMOVehicleClass_MAX; mask = mask << 1) {
321  if ((mask & permissions) == mask) {
322  ++num_allowed;
323  }
324  }
325  if (num_allowed <= (SumoVehicleClassStrings.size() - num_allowed) && num_allowed > 0) {
326  into.writeAttr(SUMO_ATTR_ALLOW, getVehicleClassNames(permissions));
327  } else {
329  }
330  }
331 }
332 
333 
334 void
336  if (preferred == SVCAll || preferred == 0) {
337  return;
338  } else {
340  }
341 }
342 
343 
345 getVehicleShapeID(const std::string& name) {
346  if (SumoVehicleShapeStrings.hasString(name)) {
347  return SumoVehicleShapeStrings.get(name);
348  } else {
349  throw InvalidArgument("Unknown vehicle shape '" + name + "'.");
350  }
351 }
352 
353 
354 bool
355 canParseVehicleShape(const std::string& shape) {
356  return SumoVehicleShapeStrings.hasString(shape);
357 }
358 
359 
360 std::string
362  return SumoVehicleShapeStrings.getString(id);
363 }
364 
365 
366 bool isRailway(SVCPermissions permissions) {
367  return (permissions & SVC_RAIL_CLASSES) > 0 && (permissions & SVC_PASSENGER) == 0;
368 }
369 
370 
371 bool
373  return permissions == SVC_SHIP;
374 }
375 
376 
377 bool
379  return (permissions & SVCAll) == 0;
380 }
381 
382 
383 bool
385  return (permissions & SVCAll) == SVC_PEDESTRIAN;
386 }
387 
388 
389 bool
391  return isForbidden(permissions) || isSidewalk(permissions);
392 }
393 
394 
395 std::map<SVCPermissions, double> parseStopOffsets(const SUMOSAXAttributes& attrs, bool& ok) {
396  const std::string vClasses = attrs.getOpt<std::string>(SUMO_ATTR_VCLASSES, nullptr, ok, "");
397  const std::string exceptions = attrs.getOpt<std::string>(SUMO_ATTR_EXCEPTIONS, nullptr, ok, "");
399  WRITE_ERROR("Simultaneous specification of vClasses and exceptions is not allowed!");
400  ok = false;
401  return std::map<SVCPermissions, double>();
402  }
403  const double value = attrs.get<double>(SUMO_ATTR_VALUE, nullptr, ok);
404 
405  int vClassBitset;
406  if (attrs.hasAttribute(SUMO_ATTR_VCLASSES)) {
407  vClassBitset = parseVehicleClasses(vClasses);
408  } else if (attrs.hasAttribute(SUMO_ATTR_EXCEPTIONS)) {
409  vClassBitset = ~parseVehicleClasses(exceptions);
410  } else {
411  // no vClasses specified, thus apply to all
412  vClassBitset = parseVehicleClasses("all");
413  }
414 
415  std::map<SVCPermissions, double> offsets;
416  offsets[vClassBitset] = value;
417  return offsets;
418 }
419 
420 
421 double
423  switch (vc) {
424  case SVC_PEDESTRIAN:
425  return 0.215;
426  case SVC_BICYCLE:
427  return 1.6;
428  case SVC_MOPED:
429  return 2.1;
430  case SVC_MOTORCYCLE:
431  return 2.2;
432  case SVC_TRUCK:
433  return 7.1;
434  case SVC_TRAILER:
435  return 16.5;
436  case SVC_BUS:
437  return 12.;
438  case SVC_COACH:
439  return 14.;
440  case SVC_TRAM:
441  return 22.;
442  case SVC_RAIL_URBAN:
443  return 36.5 * 3;
444  case SVC_RAIL:
445  return 67.5 * 2;
446  case SVC_RAIL_ELECTRIC:
447  case SVC_RAIL_FAST:
448  return 25. * 8;
449  case SVC_DELIVERY:
450  case SVC_EMERGENCY:
451  return 6.5;
452  case SVC_SHIP:
453  return 17;
454  default:
455  return 5; /*4.3*/
456  }
457 }
458 
459 
460 
461 /****************************************************************************/
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:284
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:276
static std::map< int, std::vector< std::string > > vehicleClassNamesListCached
bool canParseVehicleShape(const std::string &shape)
Checks whether the given string contains only known vehicle shape.
SUMOVehicleClass getVehicleClassID(const std::string &name)
Returns the class id of the abstract class given by its name.
double getDefaultVehicleLength(const SUMOVehicleClass vc)
Returns the default vehicle length This put into a function so it can be used by NBVehicle.
const SVCPermissions SVCAll
all VClasses are allowed
const std::string DEFAULT_VTYPE_ID("DEFAULT_VEHTYPE")
std::set< std::string > deprecatedVehicleClassesSeen
SVCPermissions invertPermissions(SVCPermissions permissions)
negate the given permissions and ensure that only relevant bits are set
static std::map< std::string, SVCPermissions > parseVehicleClassesCached
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permission is a railway edge.
StringBijection< SUMOVehicleShape >::Entry sumoVehicleShapeStringInitializer[]
const double DEFAULT_PEDESTRIAN_SPEED(5./3.6)
const SVCPermissions SVC_UNSPECIFIED
permissions not specified
const std::string DEFAULT_CONTAINERTYPE_ID("DEFAULT_CONTAINERTYPE")
StringBijection< SUMOVehicleClass >::Entry sumoVehicleClassStringInitializer[]
bool isWaterway(SVCPermissions permissions)
Returns whether an edge with the given permission is a waterway edge.
const std::string DEFAULT_PEDTYPE_ID("DEFAULT_PEDTYPE")
int getVehicleClassCompoundID(const std::string &name)
Returns the OR'ed id of the compound class given by its name.
const double DEFAULT_CONTAINER_TRANSHIP_SPEED(5./3.6)
const std::vector< std::string > & getVehicleClassNamesList(SVCPermissions permissions)
Returns the ids of the given classes, divided using a ' '.
const std::string & getVehicleClassNames(SVCPermissions permissions, bool expand)
Returns the ids of the given classes, divided using a ' '.
std::map< SVCPermissions, double > parseStopOffsets(const SUMOSAXAttributes &attrs, bool &ok)
Extract stopOffsets from attributes of stopOffset element.
void writePermissions(OutputDevice &into, SVCPermissions permissions)
writes allowed disallowed attributes if needed;
SUMOVehicleShape getVehicleShapeID(const std::string &name)
Returns the class id of the shape class given by its name.
StringBijection< SUMOVehicleClass > SumoVehicleClassStrings(sumoVehicleClassStringInitializer, SVC_CUSTOM2, false)
const double DEFAULT_VEH_PROB(1.)
bool isForbidden(SVCPermissions permissions)
Returns whether an edge with the given permission is a forbidden edge.
SVCPermissions parseVehicleClasses(const std::string &allowedS)
Parses the given definition of allowed vehicle classes into the given containers Deprecated classes g...
static std::string vehicleClassNameAll
bool isSidewalk(SVCPermissions permissions)
Returns whether an edge with the given permission is a sidewalk.
bool canParseVehicleClasses(const std::string &classes)
Checks whether the given string contains only known vehicle classes.
std::string getVehicleShapeName(SUMOVehicleShape id)
Returns the class name of the shape class given by its id.
void writePreferences(OutputDevice &into, SVCPermissions preferred)
writes allowed disallowed attributes if needed;
bool noVehicles(SVCPermissions permissions)
Returns whether an edge with the given permission forbids vehicles.
static std::map< SVCPermissions, std::string > getVehicleClassNamesCached
const std::string DEFAULT_BIKETYPE_ID("DEFAULT_BIKETYPE")
StringBijection< SUMOVehicleShape > SumoVehicleShapeStrings(sumoVehicleShapeStringInitializer, SVS_UNKNOWN, false)
const SUMOVehicleClass SUMOVehicleClass_MAX
const std::string DEFAULT_TAXITYPE_ID("DEFAULT_TAXITYPE")
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_SHIP
is an arbitrary ship
@ SVC_PRIVATE
private vehicles
@ SVC_VIP
vip vehicles
@ SVC_HOV
vehicle is a HOV
@ SVC_TRUCK
vehicle is a large transport vehicle
@ SVC_IGNORING
vehicles ignoring classes
@ SVC_CUSTOM2
is a user-defined type
@ SVC_RAIL
vehicle is a not electrified rail
@ SVC_RAIL_CLASSES
classes which drive on tracks
@ SVC_COACH
vehicle is a coach
@ SVC_PASSENGER
vehicle is a passenger car (a "normal" car)
@ SVC_BICYCLE
vehicle is a bicycle
@ SVC_RAIL_FAST
vehicle that is allowed to drive on high-speed rail tracks
@ SVC_TRAILER
vehicle is a large transport vehicle
@ SVC_CUSTOM1
is a user-defined type
@ SVC_ARMY
army vehicles
@ SVC_RAIL_ELECTRIC
rail vehicle that requires electrified tracks
@ SVC_DELIVERY
vehicle is a small delivery vehicle
@ SVC_RAIL_URBAN
vehicle is a city rail
@ SVC_MOTORCYCLE
vehicle is a motorcycle
@ SVC_EMERGENCY
public emergency vehicles
@ SVC_MOPED
vehicle is a moped
@ SVC_AUTHORITY
authorities vehicles
@ SVC_TRAM
vehicle is a light rail
@ SVC_TAXI
vehicle is a taxi
@ SVC_BUS
vehicle is a bus
@ SVC_E_VEHICLE
is an electric vehicle
@ SVC_PEDESTRIAN
pedestrian
SUMOVehicleShape
Definition of vehicle classes to differ between different appearences.
@ SVS_BICYCLE
render as a bicycle
@ SVS_FIREBRIGADE
render as a fire brigade
@ SVS_ANT
render as a giant ant
@ SVS_PASSENGER_HATCHBACK
render as a hatchback passenger vehicle ("Fliessheck")
@ SVS_TRUCK_SEMITRAILER
render as a semi-trailer transport vehicle ("Sattelschlepper")
@ SVS_RAIL
render as a rail
@ SVS_EMERGENCY
render as an emergency vehicle
@ SVS_DELIVERY
automated car (with cruise controllers)
@ SVS_MOTORCYCLE
render as a motorcycle
@ SVS_UNKNOWN
not defined
@ SVS_PASSENGER
render as a passenger vehicle
@ SVS_TRUCK
render as a transport vehicle
@ SVS_PASSENGER_SEDAN
render as a sedan passenger vehicle ("Stufenheck")
@ SVS_BUS
render as a bus
@ SVS_MOPED
render as a moped
@ SVS_E_VEHICLE
render as a (futuristic) e-vehicle
@ SVS_BUS_FLEXIBLE
render as a flexible city bus
@ SVS_BUS_TROLLEY
render as a trolley bus
@ SVS_RAIL_CARGO
render as a cargo train
@ SVS_BUS_COACH
render as a coach
@ SVS_SHIP
render as a arbitrary ship
@ SVS_RAIL_CAR
render as a (city) rail without locomotive
@ SVS_PASSENGER_WAGON
render as a wagon passenger vehicle ("Combi")
@ SVS_PASSENGER_VAN
render as a van
@ SVS_PEDESTRIAN
render as a pedestrian
@ SVS_POLICE
render as a police car
@ SVS_RICKSHAW
render as a rickshaw
@ SVS_TRUCK_1TRAILER
render as a transport vehicle with one trailer
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
@ SUMO_ATTR_PREFER
@ SUMO_ATTR_DISALLOW
@ SUMO_ATTR_ALLOW
@ SUMO_ATTR_VALUE
@ SUMO_ATTR_VCLASSES
@ SUMO_ATTR_EXCEPTIONS
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
Definition: ToString.h:250
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:60
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:239
Encapsulated SAX-Attributes.
T getOpt(int attr, const char *objectid, bool &ok, T defaultValue, bool report=true) const
Tries to read given attribute assuming it is an int.
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list.
bool hasNext()
returns the information whether further substrings exist
std::string next()
returns the next substring when it exists. Otherwise the behaviour is undefined