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 ToString.h
15 : /// @author Christian Roessel
16 : /// @author Daniel Krajzewicz
17 : /// @author Jakob Erdmann
18 : /// @author Michael Behrisch
19 : /// @date Wed, 23 Sep 2002
20 : ///
21 : // -------------------
22 : /****************************************************************************/
23 : #pragma once
24 : #include <config.h>
25 : #include <sstream>
26 : #include <string>
27 : #include <iomanip>
28 : #include <algorithm>
29 : #include <list>
30 : #ifdef HAVE_FMT
31 : #include <fmt/format.h>
32 : #endif
33 : #include <utils/xml/SUMOXMLDefinitions.h>
34 : #include <utils/common/SUMOVehicleClass.h>
35 : #include <utils/common/Named.h>
36 : #include <utils/distribution/Distribution_Parameterized.h>
37 : #include <utils/vehicle/SUMOVTypeParameter.h>
38 : #include "StdDefs.h"
39 :
40 :
41 : // ===========================================================================
42 : // class definitions
43 : // ===========================================================================
44 : /**
45 : * Template for conversions from origin format to string representation
46 : * (when supplied by c++/the stl)
47 : */
48 : template <class T>
49 73427337 : inline std::string toString(const T& t, std::streamsize accuracy = gPrecision) {
50 73427337 : std::ostringstream oss;
51 : oss.setf(std::ios::fixed, std::ios::floatfield);
52 73427337 : oss << std::setprecision(accuracy);
53 73427337 : oss << t;
54 73427337 : return oss.str();
55 73427337 : }
56 :
57 :
58 : template <>
59 77044962 : inline std::string toString(const double& val, std::streamsize accuracy) {
60 : #ifdef HAVE_FMT
61 : // for the runtime wrapper see https://github.com/fmtlib/fmt/issues/3107
62 : return fmt::format(fmt::runtime("{:.{}f}"), val, accuracy);
63 : #else
64 77044962 : std::ostringstream oss;
65 : oss.setf(std::ios::fixed, std::ios::floatfield);
66 77044962 : oss << std::setprecision(accuracy);
67 77044962 : oss << val;
68 77044962 : return oss.str();
69 : #endif
70 77044962 : }
71 :
72 :
73 : template <>
74 : inline std::string toString(const std::string& val, std::streamsize accuracy) {
75 : UNUSED_PARAMETER(accuracy);
76 65209837 : return val;
77 : }
78 :
79 :
80 : template<typename T>
81 2336 : inline std::string toHex(const T i, std::streamsize numDigits = 0) {
82 : // taken from http://stackoverflow.com/questions/5100718/int-to-hex-string-in-c
83 2336 : std::stringstream stream;
84 4672 : stream << "0x" << std::setfill('0') << std::setw(numDigits == 0 ? sizeof(T) * 2 : numDigits) << std::hex << i;
85 2336 : return stream.str();
86 2336 : }
87 :
88 :
89 : inline std::string toString(const Named* obj, std::streamsize accuracy) {
90 : UNUSED_PARAMETER(accuracy);
91 : return Named::getIDSecure(obj);
92 : }
93 :
94 :
95 : template <>
96 35404249 : inline std::string toString<SumoXMLTag>(const SumoXMLTag& tag, std::streamsize accuracy) {
97 : UNUSED_PARAMETER(accuracy);
98 35404249 : return SUMOXMLDefinitions::Tags.getString(tag);
99 : }
100 :
101 :
102 : template <>
103 118093358 : inline std::string toString<SumoXMLAttr>(const SumoXMLAttr& attr, std::streamsize accuracy) {
104 : UNUSED_PARAMETER(accuracy);
105 118093358 : return SUMOXMLDefinitions::Attrs.getString(attr);
106 : }
107 :
108 :
109 : template <>
110 84294 : inline std::string toString<SumoXMLNodeType>(const SumoXMLNodeType& nodeType, std::streamsize accuracy) {
111 : UNUSED_PARAMETER(accuracy);
112 84294 : return SUMOXMLDefinitions::NodeTypes.getString(nodeType);
113 : }
114 :
115 :
116 : template <>
117 105907 : inline std::string toString<SumoXMLEdgeFunc>(const SumoXMLEdgeFunc& edgeFunc, std::streamsize accuracy) {
118 : UNUSED_PARAMETER(accuracy);
119 105907 : return SUMOXMLDefinitions::EdgeFunctions.getString(edgeFunc);
120 : }
121 :
122 :
123 : template <>
124 1932 : inline std::string toString<SUMOVehicleClass>(const SUMOVehicleClass& vClass, std::streamsize accuracy) {
125 : UNUSED_PARAMETER(accuracy);
126 1932 : return SumoVehicleClassStrings.getString(vClass);
127 : }
128 :
129 :
130 : template <>
131 99158 : inline std::string toString<LaneSpreadFunction>(const LaneSpreadFunction& lsf, std::streamsize accuracy) {
132 : UNUSED_PARAMETER(accuracy);
133 99158 : return SUMOXMLDefinitions::LaneSpreadFunctions.getString(lsf);
134 : }
135 :
136 : template <>
137 16579 : inline std::string toString<ParkingType>(const ParkingType& pt, std::streamsize accuracy) {
138 : UNUSED_PARAMETER(accuracy);
139 16579 : return SUMOXMLDefinitions::ParkingTypes.getString(pt);
140 : }
141 :
142 : template <>
143 33 : inline std::string toString<RightOfWay>(const RightOfWay& row, std::streamsize accuracy) {
144 : UNUSED_PARAMETER(accuracy);
145 33 : return SUMOXMLDefinitions::RightOfWayValues.getString(row);
146 : }
147 :
148 : template <>
149 342 : inline std::string toString<FringeType>(const FringeType& fringeType, std::streamsize accuracy) {
150 : UNUSED_PARAMETER(accuracy);
151 342 : return SUMOXMLDefinitions::FringeTypeValues.getString(fringeType);
152 : }
153 :
154 : template <>
155 2 : inline std::string toString<RoundaboutType>(const RoundaboutType& roundaboutType, std::streamsize accuracy) {
156 : UNUSED_PARAMETER(accuracy);
157 2 : return SUMOXMLDefinitions::RoundaboutTypeValues.getString(roundaboutType);
158 : }
159 :
160 : template <>
161 1118 : inline std::string toString<PersonMode>(const PersonMode& personMode, std::streamsize accuracy) {
162 : UNUSED_PARAMETER(accuracy);
163 1118 : return SUMOXMLDefinitions::PersonModeValues.getString(personMode);
164 : }
165 :
166 : template <>
167 239563 : inline std::string toString<LinkState>(const LinkState& linkState, std::streamsize accuracy) {
168 : UNUSED_PARAMETER(accuracy);
169 239563 : return SUMOXMLDefinitions::LinkStates.getString(linkState);
170 : }
171 :
172 :
173 : template <>
174 648588 : inline std::string toString<LinkDirection>(const LinkDirection& linkDir, std::streamsize accuracy) {
175 : UNUSED_PARAMETER(accuracy);
176 648588 : return SUMOXMLDefinitions::LinkDirections.getString(linkDir);
177 : }
178 :
179 :
180 : template <>
181 2743 : inline std::string toString<TrafficLightType>(const TrafficLightType& type, std::streamsize accuracy) {
182 : UNUSED_PARAMETER(accuracy);
183 2743 : return SUMOXMLDefinitions::TrafficLightTypes.getString(type);
184 : }
185 :
186 :
187 : template <>
188 : inline std::string toString<TrafficLightLayout>(const TrafficLightLayout& layout, std::streamsize accuracy) {
189 : UNUSED_PARAMETER(accuracy);
190 : return SUMOXMLDefinitions::TrafficLightLayouts.getString(layout);
191 : }
192 :
193 :
194 : template <>
195 165 : inline std::string toString<InsertionCheck>(const InsertionCheck& check, std::streamsize accuracy) {
196 : UNUSED_PARAMETER(accuracy);
197 165 : return SUMOXMLDefinitions::InsertionChecks.getString(check);
198 : }
199 :
200 :
201 : template <>
202 3014 : inline std::string toString<LaneChangeModel>(const LaneChangeModel& model, std::streamsize accuracy) {
203 : UNUSED_PARAMETER(accuracy);
204 3014 : return SUMOXMLDefinitions::LaneChangeModels.getString(model);
205 : }
206 :
207 : template <>
208 116 : inline std::string toString<LatAlignmentDefinition>(const LatAlignmentDefinition& lad, std::streamsize accuracy) {
209 : UNUSED_PARAMETER(accuracy);
210 116 : switch (lad) {
211 : case LatAlignmentDefinition::RIGHT:
212 0 : return "right";
213 : case LatAlignmentDefinition::CENTER:
214 106 : return "center";
215 : case LatAlignmentDefinition::ARBITRARY:
216 9 : return "arbitrary";
217 : case LatAlignmentDefinition::NICE:
218 0 : return "nice";
219 : case LatAlignmentDefinition::COMPACT:
220 1 : return "compact";
221 : case LatAlignmentDefinition::LEFT:
222 0 : return "left";
223 : case LatAlignmentDefinition::GIVEN:
224 : case LatAlignmentDefinition::DEFAULT:
225 : default:
226 0 : return "";
227 : }
228 : }
229 :
230 : template <>
231 17127 : inline std::string toString<LaneChangeAction>(const LaneChangeAction& action, std::streamsize accuracy) {
232 : UNUSED_PARAMETER(accuracy);
233 17127 : std::vector<std::string> strings = SUMOXMLDefinitions::LaneChangeActions.getStrings();
234 : bool hadOne = false;
235 17127 : std::ostringstream oss;
236 342540 : for (std::vector<std::string>::const_iterator it = strings.begin(); it != strings.end(); ++it) {
237 325413 : if ((action & SUMOXMLDefinitions::LaneChangeActions.get(*it)) != 0) {
238 26305 : if (hadOne) {
239 9186 : oss << "|";
240 : } else {
241 : hadOne = true;
242 : }
243 : oss << (*it);
244 : }
245 : }
246 17127 : return oss.str();
247 17127 : }
248 :
249 : template <>
250 : inline std::string toString<Distribution_Parameterized>(const Distribution_Parameterized& dist, std::streamsize accuracy) {
251 470 : return dist.toStr(accuracy);
252 : }
253 :
254 : template <typename V>
255 : inline std::string toString(const std::vector<V*>& v, std::streamsize accuracy = gPrecision) {
256 768696 : return toString<V>(v.begin(), v.end(), accuracy);
257 : }
258 :
259 :
260 : template <typename V>
261 770128 : inline std::string toString(const typename std::vector<V*>::const_iterator& b, const typename std::vector<V*>::const_iterator& e, std::streamsize accuracy = gPrecision) {
262 : UNUSED_PARAMETER(accuracy);
263 770128 : std::ostringstream oss;
264 4128807 : for (typename std::vector<V*>::const_iterator it = b; it != e; ++it) {
265 3358679 : if (it != b) {
266 2599489 : oss << " ";
267 : }
268 6717358 : oss << Named::getIDSecure(*it);
269 : }
270 770128 : return oss.str();
271 770128 : }
272 :
273 : template <typename V>
274 : inline std::string toString(const std::list<V*>& v, std::streamsize accuracy = gPrecision) {
275 30 : return toString<V>(v.begin(), v.end(), accuracy);
276 : }
277 :
278 : template <typename V>
279 30 : inline std::string toString(const typename std::list<V*>::const_iterator& b, const typename std::list<V*>::const_iterator& e, std::streamsize accuracy = gPrecision) {
280 : UNUSED_PARAMETER(accuracy);
281 30 : std::ostringstream oss;
282 94 : for (typename std::list<V*>::const_iterator it = b; it != e; ++it) {
283 64 : if (it != b) {
284 39 : oss << " ";
285 : }
286 128 : oss << Named::getIDSecure(*it);
287 : }
288 30 : return oss.str();
289 30 : }
290 :
291 :
292 :
293 : //template <typename V>
294 : //inline std::string toString(const std::vector<V>& v, std::streamsize accuracy = gPrecision) {
295 : // return toString<V>(v.begin(), v.end(), accuracy);
296 : //}
297 : //
298 : //
299 : //template <typename V>
300 : //inline std::string toString(const typename std::vector<V>::const_iterator& b, const typename std::vector<V>::const_iterator& e, std::streamsize accuracy = gPrecision) {
301 : // UNUSED_PARAMETER(accuracy);
302 : // std::ostringstream oss;
303 : // for (typename std::vector<V>::const_iterator it = b; it != e; ++it) {
304 : // if (it != b) {
305 : // oss << " ";
306 : // }
307 : // oss << Named::getIDSecure(*it);
308 : // }
309 : // return oss.str();
310 : //}
311 :
312 :
313 : template <typename T, typename T_BETWEEN>
314 25926701 : inline std::string joinToString(const std::vector<T>& v, const T_BETWEEN& between, std::streamsize accuracy = gPrecision) {
315 25926701 : std::ostringstream oss;
316 : bool connect = false;
317 54064487 : for (typename std::vector<T>::const_iterator it = v.begin(); it != v.end(); ++it) {
318 28137786 : if (connect) {
319 4643006 : oss << toString(between, accuracy);
320 : } else {
321 : connect = true;
322 : }
323 29700789 : oss << toString(*it, accuracy);
324 : }
325 25926701 : return oss.str();
326 25926701 : }
327 :
328 :
329 : template <typename T, typename T_BETWEEN>
330 24535 : inline std::string joinToStringSorting(const std::vector<T>& v, const T_BETWEEN& between, std::streamsize accuracy = gPrecision) {
331 24535 : std::vector<T> sorted(v);
332 24535 : std::sort(sorted.begin(), sorted.end());
333 49070 : return joinToString(sorted, between, accuracy);
334 24535 : }
335 :
336 :
337 : template <typename T, typename T_BETWEEN>
338 148 : inline std::string joinNamedToStringSorting(const std::set<T*>& ns, const T_BETWEEN& between) {
339 : std::vector<std::string> ids;
340 484 : for (T* n : ns) {
341 672 : ids.push_back(Named::getIDSecure(n));
342 : }
343 296 : return joinToStringSorting(ids, between);
344 148 : }
345 :
346 : template <typename T, typename T_BETWEEN>
347 : inline std::string joinNamedToStringSorting(const std::set<T*, ComparatorIdLess>& ns, const T_BETWEEN& between) {
348 : std::vector<std::string> ids;
349 : for (T* n : ns) {
350 : ids.push_back(Named::getIDSecure(n));
351 : }
352 : return joinToStringSorting(ids, between);
353 : }
354 :
355 :
356 : template <typename T, typename C, typename T_BETWEEN>
357 3263 : inline std::string joinNamedToString(const std::set<T*, C>& ns, const T_BETWEEN& between) {
358 : std::vector<std::string> ids;
359 14322 : for (T* n : ns) {
360 22118 : ids.push_back(Named::getIDSecure(n));
361 : }
362 6526 : return joinToString(ids, between);
363 3263 : }
364 :
365 :
366 : template <typename KEY, typename VAL, typename T_BETWEEN, typename T_BETWEEN_KEYVAL>
367 : inline std::string joinNamedToString(const std::map<KEY, VAL, ComparatorIdLess>& s, const T_BETWEEN& between, const T_BETWEEN_KEYVAL& between_keyval, std::streamsize accuracy = gPrecision) {
368 : std::ostringstream oss;
369 : bool connect = false;
370 : for (typename std::map<KEY, VAL>::const_iterator it = s.begin(); it != s.end(); ++it) {
371 : if (connect) {
372 : oss << toString(between, accuracy);
373 : } else {
374 : connect = true;
375 : }
376 : oss << Named::getIDSecure(it->first) << between_keyval << toString(it->second, accuracy);
377 : }
378 : return oss.str();
379 : }
380 :
381 :
382 : template <typename V>
383 34 : inline std::string toString(const std::set<V*>& v, std::streamsize accuracy = gPrecision) {
384 : UNUSED_PARAMETER(accuracy);
385 : std::vector<std::string> ids;
386 110 : for (typename std::set<V*>::const_iterator it = v.begin(); it != v.end(); ++it) {
387 76 : ids.push_back((*it)->getID());
388 : }
389 68 : return joinToStringSorting(ids, " ");
390 34 : }
391 :
392 :
393 : template <typename V>
394 5586 : inline std::string toString(const std::set<V*, ComparatorNumericalIdLess>& v, std::streamsize accuracy = gPrecision) {
395 : UNUSED_PARAMETER(accuracy);
396 : std::vector<std::string> ids;
397 11532 : for (typename std::set<V*, ComparatorNumericalIdLess>::const_iterator it = v.begin(); it != v.end(); ++it) {
398 5946 : ids.push_back((*it)->getID());
399 : }
400 11172 : return joinToStringSorting(ids, " ");
401 5586 : }
402 :
403 :
404 : template <>
405 : inline std::string toString(const std::vector<int>& v, std::streamsize accuracy) {
406 168 : return joinToString(v, " ", accuracy);
407 : }
408 :
409 :
410 : template <>
411 : inline std::string toString(const std::vector<long long int>& v, std::streamsize accuracy) {
412 4409 : return joinToString(v, " ", accuracy);
413 : }
414 :
415 :
416 : template <>
417 : inline std::string toString(const std::vector<double>& v, std::streamsize accuracy) {
418 212966 : return joinToString(v, " ", accuracy);
419 : }
420 :
421 :
422 : template <typename V, typename W>
423 : inline std::string toString(const std::vector<std::pair<V, W> >& v, std::streamsize accuracy = gPrecision, const std::string& between = ";", const std::string& between2 = ",") {
424 : std::ostringstream oss;
425 : oss << std::setprecision(accuracy);
426 : bool connect = false;
427 : for (auto it : v) {
428 : if (connect) {
429 : oss << toString(between, accuracy);
430 : } else {
431 : connect = true;
432 : }
433 : oss << toString(it.first) << between2 << toString(it.second);
434 : }
435 : return oss.str();
436 : }
437 :
438 :
439 : template <typename T, typename T_BETWEEN>
440 102724 : inline std::string joinToString(const std::set<T>& s, const T_BETWEEN& between, std::streamsize accuracy = gPrecision) {
441 102724 : std::ostringstream oss;
442 : bool connect = false;
443 206831 : for (typename std::set<T>::const_iterator it = s.begin(); it != s.end(); ++it) {
444 104107 : if (connect) {
445 2786 : oss << toString(between, accuracy);
446 : } else {
447 : connect = true;
448 : }
449 104107 : oss << toString(*it, accuracy);
450 : }
451 102724 : return oss.str();
452 102724 : }
453 :
454 :
455 : template <>
456 : inline std::string toString(const std::vector<std::string>& v, std::streamsize) {
457 236570 : return joinToString(v, " ");
458 : }
459 :
460 :
461 : template <>
462 : inline std::string toString(const std::set<std::string>& v, std::streamsize) {
463 3619 : return joinToString(v, " ");
464 : }
465 :
466 :
467 : template <typename KEY, typename VAL, typename T_BETWEEN, typename T_BETWEEN_KEYVAL>
468 11 : inline std::string joinToString(const std::map<KEY, VAL>& s, const T_BETWEEN& between, const T_BETWEEN_KEYVAL& between_keyval, std::streamsize accuracy = gPrecision) {
469 11 : std::ostringstream oss;
470 : bool connect = false;
471 33 : for (typename std::map<KEY, VAL>::const_iterator it = s.begin(); it != s.end(); ++it) {
472 22 : if (connect) {
473 22 : oss << toString(between, accuracy);
474 : } else {
475 : connect = true;
476 : }
477 66 : oss << toString(it->first, accuracy) << between_keyval << toString(it->second, accuracy);
478 : }
479 11 : return oss.str();
480 11 : }
481 :
482 :
483 : template <>
484 : inline std::string toString(const Parameterised::Map& v, std::streamsize) {
485 : return joinToString(v, ", ", ":");
486 : }
487 :
488 : template <>
489 2677 : inline std::string toString(const MMVersion& v, std::streamsize) {
490 : // we only need higher accuracy on the minor version for hotfix releases
491 8031 : return toString(v.first) + "." + toString(v.second, 0);
492 : }
|