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 70372670 : inline std::string toString(const T& t, std::streamsize accuracy = gPrecision) {
50 70372670 : std::ostringstream oss;
51 : oss.setf(std::ios::fixed, std::ios::floatfield);
52 70372670 : oss << std::setprecision(accuracy);
53 70372670 : oss << t;
54 70372670 : return oss.str();
55 70372670 : }
56 :
57 :
58 : template <>
59 72277585 : inline std::string toString(const double& val, std::streamsize accuracy) {
60 : #ifdef HAVE_FMT
61 : return fmt::format("{:.{}f}", val, accuracy);
62 : #else
63 72277585 : std::ostringstream oss;
64 : oss.setf(std::ios::fixed, std::ios::floatfield);
65 72277585 : oss << std::setprecision(accuracy);
66 72277585 : oss << val;
67 72277585 : return oss.str();
68 : #endif
69 72277585 : }
70 :
71 :
72 : template <>
73 : inline std::string toString(const std::string& val, std::streamsize accuracy) {
74 : UNUSED_PARAMETER(accuracy);
75 57172456 : return val;
76 : }
77 :
78 :
79 : template<typename T>
80 2337 : inline std::string toHex(const T i, std::streamsize numDigits = 0) {
81 : // taken from http://stackoverflow.com/questions/5100718/int-to-hex-string-in-c
82 2337 : std::stringstream stream;
83 4674 : stream << "0x" << std::setfill('0') << std::setw(numDigits == 0 ? sizeof(T) * 2 : numDigits) << std::hex << i;
84 2337 : return stream.str();
85 2337 : }
86 :
87 :
88 : inline std::string toString(const Named* obj, std::streamsize accuracy) {
89 : UNUSED_PARAMETER(accuracy);
90 : return Named::getIDSecure(obj);
91 : }
92 :
93 :
94 : template <>
95 32127539 : inline std::string toString<SumoXMLTag>(const SumoXMLTag& tag, std::streamsize accuracy) {
96 : UNUSED_PARAMETER(accuracy);
97 32127539 : return SUMOXMLDefinitions::Tags.getString(tag);
98 : }
99 :
100 :
101 : template <>
102 104736786 : inline std::string toString<SumoXMLAttr>(const SumoXMLAttr& attr, std::streamsize accuracy) {
103 : UNUSED_PARAMETER(accuracy);
104 104736786 : return SUMOXMLDefinitions::Attrs.getString(attr);
105 : }
106 :
107 :
108 : template <>
109 77162 : inline std::string toString<SumoXMLNodeType>(const SumoXMLNodeType& nodeType, std::streamsize accuracy) {
110 : UNUSED_PARAMETER(accuracy);
111 77162 : return SUMOXMLDefinitions::NodeTypes.getString(nodeType);
112 : }
113 :
114 :
115 : template <>
116 105863 : inline std::string toString<SumoXMLEdgeFunc>(const SumoXMLEdgeFunc& edgeFunc, std::streamsize accuracy) {
117 : UNUSED_PARAMETER(accuracy);
118 105863 : return SUMOXMLDefinitions::EdgeFunctions.getString(edgeFunc);
119 : }
120 :
121 :
122 : template <>
123 1940 : inline std::string toString<SUMOVehicleClass>(const SUMOVehicleClass& vClass, std::streamsize accuracy) {
124 : UNUSED_PARAMETER(accuracy);
125 1940 : return SumoVehicleClassStrings.getString(vClass);
126 : }
127 :
128 :
129 : template <>
130 93699 : inline std::string toString<LaneSpreadFunction>(const LaneSpreadFunction& lsf, std::streamsize accuracy) {
131 : UNUSED_PARAMETER(accuracy);
132 93699 : return SUMOXMLDefinitions::LaneSpreadFunctions.getString(lsf);
133 : }
134 :
135 : template <>
136 12577 : inline std::string toString<ParkingType>(const ParkingType& pt, std::streamsize accuracy) {
137 : UNUSED_PARAMETER(accuracy);
138 12577 : return SUMOXMLDefinitions::ParkingTypes.getString(pt);
139 : }
140 :
141 : template <>
142 33 : inline std::string toString<RightOfWay>(const RightOfWay& row, std::streamsize accuracy) {
143 : UNUSED_PARAMETER(accuracy);
144 33 : return SUMOXMLDefinitions::RightOfWayValues.getString(row);
145 : }
146 :
147 : template <>
148 333 : inline std::string toString<FringeType>(const FringeType& fringeType, std::streamsize accuracy) {
149 : UNUSED_PARAMETER(accuracy);
150 333 : return SUMOXMLDefinitions::FringeTypeValues.getString(fringeType);
151 : }
152 :
153 : template <>
154 2 : inline std::string toString<RoundaboutType>(const RoundaboutType& roundaboutType, std::streamsize accuracy) {
155 : UNUSED_PARAMETER(accuracy);
156 2 : return SUMOXMLDefinitions::RoundaboutTypeValues.getString(roundaboutType);
157 : }
158 :
159 : template <>
160 1118 : inline std::string toString<PersonMode>(const PersonMode& personMode, std::streamsize accuracy) {
161 : UNUSED_PARAMETER(accuracy);
162 1118 : return SUMOXMLDefinitions::PersonModeValues.getString(personMode);
163 : }
164 :
165 : template <>
166 208179 : inline std::string toString<LinkState>(const LinkState& linkState, std::streamsize accuracy) {
167 : UNUSED_PARAMETER(accuracy);
168 208179 : return SUMOXMLDefinitions::LinkStates.getString(linkState);
169 : }
170 :
171 :
172 : template <>
173 617564 : inline std::string toString<LinkDirection>(const LinkDirection& linkDir, std::streamsize accuracy) {
174 : UNUSED_PARAMETER(accuracy);
175 617564 : return SUMOXMLDefinitions::LinkDirections.getString(linkDir);
176 : }
177 :
178 :
179 : template <>
180 2503 : inline std::string toString<TrafficLightType>(const TrafficLightType& type, std::streamsize accuracy) {
181 : UNUSED_PARAMETER(accuracy);
182 2503 : return SUMOXMLDefinitions::TrafficLightTypes.getString(type);
183 : }
184 :
185 :
186 : template <>
187 : inline std::string toString<TrafficLightLayout>(const TrafficLightLayout& layout, std::streamsize accuracy) {
188 : UNUSED_PARAMETER(accuracy);
189 : return SUMOXMLDefinitions::TrafficLightLayouts.getString(layout);
190 : }
191 :
192 :
193 : template <>
194 165 : inline std::string toString<InsertionCheck>(const InsertionCheck& check, std::streamsize accuracy) {
195 : UNUSED_PARAMETER(accuracy);
196 165 : return SUMOXMLDefinitions::InsertionChecks.getString(check);
197 : }
198 :
199 :
200 : template <>
201 3014 : inline std::string toString<LaneChangeModel>(const LaneChangeModel& model, std::streamsize accuracy) {
202 : UNUSED_PARAMETER(accuracy);
203 3014 : return SUMOXMLDefinitions::LaneChangeModels.getString(model);
204 : }
205 :
206 : template <>
207 116 : inline std::string toString<LatAlignmentDefinition>(const LatAlignmentDefinition& lad, std::streamsize accuracy) {
208 : UNUSED_PARAMETER(accuracy);
209 116 : switch (lad) {
210 : case LatAlignmentDefinition::RIGHT:
211 0 : return "right";
212 : case LatAlignmentDefinition::CENTER:
213 106 : return "center";
214 : case LatAlignmentDefinition::ARBITRARY:
215 9 : return "arbitrary";
216 : case LatAlignmentDefinition::NICE:
217 0 : return "nice";
218 : case LatAlignmentDefinition::COMPACT:
219 1 : return "compact";
220 : case LatAlignmentDefinition::LEFT:
221 0 : return "left";
222 : case LatAlignmentDefinition::GIVEN:
223 : case LatAlignmentDefinition::DEFAULT:
224 : default:
225 0 : return "";
226 : }
227 : }
228 :
229 : template <>
230 16637 : inline std::string toString<LaneChangeAction>(const LaneChangeAction& action, std::streamsize accuracy) {
231 : UNUSED_PARAMETER(accuracy);
232 16637 : std::vector<std::string> strings = SUMOXMLDefinitions::LaneChangeActions.getStrings();
233 : bool hadOne = false;
234 16637 : std::ostringstream oss;
235 332740 : for (std::vector<std::string>::const_iterator it = strings.begin(); it != strings.end(); ++it) {
236 316103 : if ((action & SUMOXMLDefinitions::LaneChangeActions.get(*it)) != 0) {
237 25514 : if (hadOne) {
238 8882 : oss << "|";
239 : } else {
240 : hadOne = true;
241 : }
242 : oss << (*it);
243 : }
244 : }
245 16637 : return oss.str();
246 16637 : }
247 :
248 : template <>
249 : inline std::string toString<Distribution_Parameterized>(const Distribution_Parameterized& dist, std::streamsize accuracy) {
250 464 : return dist.toStr(accuracy);
251 : }
252 :
253 : template <typename V>
254 : inline std::string toString(const std::vector<V*>& v, std::streamsize accuracy = gPrecision) {
255 760471 : return toString<V>(v.begin(), v.end(), accuracy);
256 : }
257 :
258 :
259 : template <typename V>
260 761903 : inline std::string toString(const typename std::vector<V*>::const_iterator& b, const typename std::vector<V*>::const_iterator& e, std::streamsize accuracy = gPrecision) {
261 : UNUSED_PARAMETER(accuracy);
262 761903 : std::ostringstream oss;
263 4081030 : for (typename std::vector<V*>::const_iterator it = b; it != e; ++it) {
264 3319127 : if (it != b) {
265 2566645 : oss << " ";
266 : }
267 6638254 : oss << Named::getIDSecure(*it);
268 : }
269 761903 : return oss.str();
270 761903 : }
271 :
272 : template <typename V>
273 : inline std::string toString(const std::list<V*>& v, std::streamsize accuracy = gPrecision) {
274 8 : return toString<V>(v.begin(), v.end(), accuracy);
275 : }
276 :
277 : template <typename V>
278 8 : inline std::string toString(const typename std::list<V*>::const_iterator& b, const typename std::list<V*>::const_iterator& e, std::streamsize accuracy = gPrecision) {
279 : UNUSED_PARAMETER(accuracy);
280 8 : std::ostringstream oss;
281 41 : for (typename std::list<V*>::const_iterator it = b; it != e; ++it) {
282 33 : if (it != b) {
283 27 : oss << " ";
284 : }
285 66 : oss << Named::getIDSecure(*it);
286 : }
287 8 : return oss.str();
288 8 : }
289 :
290 :
291 :
292 : //template <typename V>
293 : //inline std::string toString(const std::vector<V>& v, std::streamsize accuracy = gPrecision) {
294 : // return toString<V>(v.begin(), v.end(), accuracy);
295 : //}
296 : //
297 : //
298 : //template <typename V>
299 : //inline std::string toString(const typename std::vector<V>::const_iterator& b, const typename std::vector<V>::const_iterator& e, std::streamsize accuracy = gPrecision) {
300 : // UNUSED_PARAMETER(accuracy);
301 : // std::ostringstream oss;
302 : // for (typename std::vector<V>::const_iterator it = b; it != e; ++it) {
303 : // if (it != b) {
304 : // oss << " ";
305 : // }
306 : // oss << Named::getIDSecure(*it);
307 : // }
308 : // return oss.str();
309 : //}
310 :
311 :
312 : template <typename T, typename T_BETWEEN>
313 22633667 : inline std::string joinToString(const std::vector<T>& v, const T_BETWEEN& between, std::streamsize accuracy = gPrecision) {
314 22633667 : std::ostringstream oss;
315 : bool connect = false;
316 47435698 : for (typename std::vector<T>::const_iterator it = v.begin(); it != v.end(); ++it) {
317 24802031 : if (connect) {
318 4433731 : oss << toString(between, accuracy);
319 : } else {
320 : connect = true;
321 : }
322 26300706 : oss << toString(*it, accuracy);
323 : }
324 22633667 : return oss.str();
325 22633667 : }
326 :
327 :
328 : template <typename T, typename T_BETWEEN>
329 22428 : inline std::string joinToStringSorting(const std::vector<T>& v, const T_BETWEEN& between, std::streamsize accuracy = gPrecision) {
330 22428 : std::vector<T> sorted(v);
331 22428 : std::sort(sorted.begin(), sorted.end());
332 44856 : return joinToString(sorted, between, accuracy);
333 22428 : }
334 :
335 :
336 : template <typename T, typename T_BETWEEN>
337 96 : inline std::string joinNamedToStringSorting(const std::set<T*>& ns, const T_BETWEEN& between) {
338 : std::vector<std::string> ids;
339 360 : for (T* n : ns) {
340 528 : ids.push_back(Named::getIDSecure(n));
341 : }
342 192 : return joinToStringSorting(ids, between);
343 96 : }
344 :
345 : template <typename T, typename T_BETWEEN>
346 : inline std::string joinNamedToStringSorting(const std::set<T*, ComparatorIdLess>& ns, const T_BETWEEN& between) {
347 : std::vector<std::string> ids;
348 : for (T* n : ns) {
349 : ids.push_back(Named::getIDSecure(n));
350 : }
351 : return joinToStringSorting(ids, between);
352 : }
353 :
354 :
355 : template <typename T, typename C, typename T_BETWEEN>
356 3261 : inline std::string joinNamedToString(const std::set<T*, C>& ns, const T_BETWEEN& between) {
357 : std::vector<std::string> ids;
358 14306 : for (T* n : ns) {
359 22090 : ids.push_back(Named::getIDSecure(n));
360 : }
361 6522 : return joinToString(ids, between);
362 3261 : }
363 :
364 :
365 : template <typename KEY, typename VAL, typename T_BETWEEN, typename T_BETWEEN_KEYVAL>
366 : 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) {
367 : std::ostringstream oss;
368 : bool connect = false;
369 : for (typename std::map<KEY, VAL>::const_iterator it = s.begin(); it != s.end(); ++it) {
370 : if (connect) {
371 : oss << toString(between, accuracy);
372 : } else {
373 : connect = true;
374 : }
375 : oss << Named::getIDSecure(it->first) << between_keyval << toString(it->second, accuracy);
376 : }
377 : return oss.str();
378 : }
379 :
380 :
381 : template <typename V>
382 5006 : inline std::string toString(const std::set<V*>& v, std::streamsize accuracy = gPrecision) {
383 : UNUSED_PARAMETER(accuracy);
384 : std::vector<std::string> ids;
385 10276 : for (typename std::set<V*>::const_iterator it = v.begin(); it != v.end(); ++it) {
386 5270 : ids.push_back((*it)->getID());
387 : }
388 10012 : return joinToStringSorting(ids, " ");
389 5006 : }
390 :
391 :
392 : template <typename V>
393 : inline std::string toString(const std::set<V*, ComparatorNumericalIdLess>& v, std::streamsize accuracy = gPrecision) {
394 : UNUSED_PARAMETER(accuracy);
395 : std::vector<std::string> ids;
396 : for (typename std::set<V*, ComparatorNumericalIdLess>::const_iterator it = v.begin(); it != v.end(); ++it) {
397 : ids.push_back((*it)->getID());
398 : }
399 : return joinToStringSorting(ids, " ");
400 : }
401 :
402 :
403 : template <>
404 : inline std::string toString(const std::vector<int>& v, std::streamsize accuracy) {
405 168 : return joinToString(v, " ", accuracy);
406 : }
407 :
408 :
409 : template <>
410 : inline std::string toString(const std::vector<long long int>& v, std::streamsize accuracy) {
411 1814 : return joinToString(v, " ", accuracy);
412 : }
413 :
414 :
415 : template <>
416 : inline std::string toString(const std::vector<double>& v, std::streamsize accuracy) {
417 209570 : return joinToString(v, " ", accuracy);
418 : }
419 :
420 :
421 : template <typename V, typename W>
422 : inline std::string toString(const std::vector<std::pair<V, W> >& v, std::streamsize accuracy = gPrecision, const std::string& between = ";", const std::string& between2 = ",") {
423 : std::ostringstream oss;
424 : oss << std::setprecision(accuracy);
425 : bool connect = false;
426 : for (auto it : v) {
427 : if (connect) {
428 : oss << toString(between, accuracy);
429 : } else {
430 : connect = true;
431 : }
432 : oss << toString(it.first) << between2 << toString(it.second);
433 : }
434 : return oss.str();
435 : }
436 :
437 :
438 : template <typename T, typename T_BETWEEN>
439 101787 : inline std::string joinToString(const std::set<T>& s, const T_BETWEEN& between, std::streamsize accuracy = gPrecision) {
440 101787 : std::ostringstream oss;
441 : bool connect = false;
442 204872 : for (typename std::set<T>::const_iterator it = s.begin(); it != s.end(); ++it) {
443 103085 : if (connect) {
444 2616 : oss << toString(between, accuracy);
445 : } else {
446 : connect = true;
447 : }
448 103085 : oss << toString(*it, accuracy);
449 : }
450 101787 : return oss.str();
451 101787 : }
452 :
453 :
454 : template <>
455 : inline std::string toString(const std::vector<std::string>& v, std::streamsize) {
456 210594 : return joinToString(v, " ");
457 : }
458 :
459 :
460 : template <>
461 : inline std::string toString(const std::set<std::string>& v, std::streamsize) {
462 2680 : return joinToString(v, " ");
463 : }
464 :
465 :
466 : template <typename KEY, typename VAL, typename T_BETWEEN, typename T_BETWEEN_KEYVAL>
467 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) {
468 11 : std::ostringstream oss;
469 : bool connect = false;
470 33 : for (typename std::map<KEY, VAL>::const_iterator it = s.begin(); it != s.end(); ++it) {
471 22 : if (connect) {
472 22 : oss << toString(between, accuracy);
473 : } else {
474 : connect = true;
475 : }
476 66 : oss << toString(it->first, accuracy) << between_keyval << toString(it->second, accuracy);
477 : }
478 11 : return oss.str();
479 11 : }
480 :
481 :
482 : template <>
483 : inline std::string toString(const Parameterised::Map& v, std::streamsize) {
484 : return joinToString(v, ", ", ":");
485 : }
486 :
487 : template <>
488 2639 : inline std::string toString(const MMVersion& v, std::streamsize) {
489 : // we only need higher accuracy on the minor version for hotfix releases
490 7917 : return toString(v.first) + "." + toString(v.second, 0);
491 : }
|