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 : #include <utils/xml/SUMOXMLDefinitions.h>
31 : #include <utils/common/SUMOVehicleClass.h>
32 : #include <utils/common/Named.h>
33 : #include <utils/distribution/Distribution_Parameterized.h>
34 : #include <utils/vehicle/SUMOVTypeParameter.h>
35 : #include "StdDefs.h"
36 :
37 :
38 : // ===========================================================================
39 : // class definitions
40 : // ===========================================================================
41 : /**
42 : * Template for conversions from origin format to string representation
43 : * (when supplied by c++/the stl)
44 : */
45 : template <class T>
46 145761116 : inline std::string toString(const T& t, std::streamsize accuracy = gPrecision) {
47 145761116 : std::ostringstream oss;
48 : oss.setf(std::ios::fixed, std::ios::floatfield);
49 145761116 : oss << std::setprecision(accuracy);
50 115662842 : oss << t;
51 145761116 : return oss.str();
52 145761116 : }
53 :
54 :
55 : template<typename T>
56 2580 : inline std::string toHex(const T i, std::streamsize numDigits = 0) {
57 : // taken from http://stackoverflow.com/questions/5100718/int-to-hex-string-in-c
58 2580 : std::stringstream stream;
59 5160 : stream << "0x" << std::setfill('0') << std::setw(numDigits == 0 ? sizeof(T) * 2 : numDigits) << std::hex << i;
60 2580 : return stream.str();
61 2580 : }
62 :
63 :
64 : inline std::string toString(const Named* obj, std::streamsize accuracy) {
65 : UNUSED_PARAMETER(accuracy);
66 : return Named::getIDSecure(obj);
67 : }
68 :
69 :
70 : template <>
71 28686344 : inline std::string toString<SumoXMLTag>(const SumoXMLTag& tag, std::streamsize accuracy) {
72 : UNUSED_PARAMETER(accuracy);
73 28686344 : return SUMOXMLDefinitions::Tags.getString(tag);
74 : }
75 :
76 :
77 : template <>
78 83195613 : inline std::string toString<SumoXMLAttr>(const SumoXMLAttr& attr, std::streamsize accuracy) {
79 : UNUSED_PARAMETER(accuracy);
80 83195613 : return SUMOXMLDefinitions::Attrs.getString(attr);
81 : }
82 :
83 :
84 : template <>
85 75020 : inline std::string toString<SumoXMLNodeType>(const SumoXMLNodeType& nodeType, std::streamsize accuracy) {
86 : UNUSED_PARAMETER(accuracy);
87 75020 : return SUMOXMLDefinitions::NodeTypes.getString(nodeType);
88 : }
89 :
90 :
91 : template <>
92 105467 : inline std::string toString<SumoXMLEdgeFunc>(const SumoXMLEdgeFunc& edgeFunc, std::streamsize accuracy) {
93 : UNUSED_PARAMETER(accuracy);
94 105467 : return SUMOXMLDefinitions::EdgeFunctions.getString(edgeFunc);
95 : }
96 :
97 :
98 : template <>
99 1944 : inline std::string toString<SUMOVehicleClass>(const SUMOVehicleClass& vClass, std::streamsize accuracy) {
100 : UNUSED_PARAMETER(accuracy);
101 1944 : return SumoVehicleClassStrings.getString(vClass);
102 : }
103 :
104 :
105 : template <>
106 73771 : inline std::string toString<LaneSpreadFunction>(const LaneSpreadFunction& lsf, std::streamsize accuracy) {
107 : UNUSED_PARAMETER(accuracy);
108 73771 : return SUMOXMLDefinitions::LaneSpreadFunctions.getString(lsf);
109 : }
110 :
111 : template <>
112 12478 : inline std::string toString<ParkingType>(const ParkingType& pt, std::streamsize accuracy) {
113 : UNUSED_PARAMETER(accuracy);
114 12478 : return SUMOXMLDefinitions::ParkingTypes.getString(pt);
115 : }
116 :
117 : template <>
118 33 : inline std::string toString<RightOfWay>(const RightOfWay& row, std::streamsize accuracy) {
119 : UNUSED_PARAMETER(accuracy);
120 33 : return SUMOXMLDefinitions::RightOfWayValues.getString(row);
121 : }
122 :
123 : template <>
124 331 : inline std::string toString<FringeType>(const FringeType& fringeType, std::streamsize accuracy) {
125 : UNUSED_PARAMETER(accuracy);
126 331 : return SUMOXMLDefinitions::FringeTypeValues.getString(fringeType);
127 : }
128 :
129 : template <>
130 2 : inline std::string toString<RoundaboutType>(const RoundaboutType& roundaboutType, std::streamsize accuracy) {
131 : UNUSED_PARAMETER(accuracy);
132 2 : return SUMOXMLDefinitions::RoundaboutTypeValues.getString(roundaboutType);
133 : }
134 :
135 : template <>
136 1118 : inline std::string toString<PersonMode>(const PersonMode& personMode, std::streamsize accuracy) {
137 : UNUSED_PARAMETER(accuracy);
138 1118 : return SUMOXMLDefinitions::PersonModeValues.getString(personMode);
139 : }
140 :
141 : template <>
142 202886 : inline std::string toString<LinkState>(const LinkState& linkState, std::streamsize accuracy) {
143 : UNUSED_PARAMETER(accuracy);
144 202886 : return SUMOXMLDefinitions::LinkStates.getString(linkState);
145 : }
146 :
147 :
148 : template <>
149 611438 : inline std::string toString<LinkDirection>(const LinkDirection& linkDir, std::streamsize accuracy) {
150 : UNUSED_PARAMETER(accuracy);
151 611438 : return SUMOXMLDefinitions::LinkDirections.getString(linkDir);
152 : }
153 :
154 :
155 : template <>
156 2448 : inline std::string toString<TrafficLightType>(const TrafficLightType& type, std::streamsize accuracy) {
157 : UNUSED_PARAMETER(accuracy);
158 2448 : return SUMOXMLDefinitions::TrafficLightTypes.getString(type);
159 : }
160 :
161 :
162 : template <>
163 : inline std::string toString<TrafficLightLayout>(const TrafficLightLayout& layout, std::streamsize accuracy) {
164 : UNUSED_PARAMETER(accuracy);
165 : return SUMOXMLDefinitions::TrafficLightLayouts.getString(layout);
166 : }
167 :
168 :
169 : template <>
170 165 : inline std::string toString<InsertionCheck>(const InsertionCheck& check, std::streamsize accuracy) {
171 : UNUSED_PARAMETER(accuracy);
172 165 : return SUMOXMLDefinitions::InsertionChecks.getString(check);
173 : }
174 :
175 :
176 : template <>
177 3016 : inline std::string toString<LaneChangeModel>(const LaneChangeModel& model, std::streamsize accuracy) {
178 : UNUSED_PARAMETER(accuracy);
179 3016 : return SUMOXMLDefinitions::LaneChangeModels.getString(model);
180 : }
181 :
182 : template <>
183 116 : inline std::string toString<LatAlignmentDefinition>(const LatAlignmentDefinition& lad, std::streamsize accuracy) {
184 : UNUSED_PARAMETER(accuracy);
185 116 : switch (lad) {
186 : case LatAlignmentDefinition::RIGHT:
187 0 : return "right";
188 : case LatAlignmentDefinition::CENTER:
189 106 : return "center";
190 : case LatAlignmentDefinition::ARBITRARY:
191 9 : return "arbitrary";
192 : case LatAlignmentDefinition::NICE:
193 0 : return "nice";
194 : case LatAlignmentDefinition::COMPACT:
195 1 : return "compact";
196 : case LatAlignmentDefinition::LEFT:
197 0 : return "left";
198 : case LatAlignmentDefinition::GIVEN:
199 : case LatAlignmentDefinition::DEFAULT:
200 : default:
201 0 : return "";
202 : }
203 : }
204 :
205 : template <>
206 16172 : inline std::string toString<LaneChangeAction>(const LaneChangeAction& action, std::streamsize accuracy) {
207 : UNUSED_PARAMETER(accuracy);
208 16172 : std::vector<std::string> strings = SUMOXMLDefinitions::LaneChangeActions.getStrings();
209 : bool hadOne = false;
210 16172 : std::ostringstream oss;
211 323440 : for (std::vector<std::string>::const_iterator it = strings.begin(); it != strings.end(); ++it) {
212 307268 : if ((action & SUMOXMLDefinitions::LaneChangeActions.get(*it)) != 0) {
213 24592 : if (hadOne) {
214 8425 : oss << "|";
215 : } else {
216 : hadOne = true;
217 : }
218 : oss << (*it);
219 : }
220 : }
221 16172 : return oss.str();
222 16172 : }
223 :
224 : template <>
225 : inline std::string toString<Distribution_Parameterized>(const Distribution_Parameterized& dist, std::streamsize accuracy) {
226 464 : return dist.toStr(accuracy);
227 : }
228 :
229 : template <typename V>
230 : inline std::string toString(const std::vector<V*>& v, std::streamsize accuracy = gPrecision) {
231 759136 : return toString<V>(v.begin(), v.end(), accuracy);
232 : }
233 :
234 :
235 : template <typename V>
236 760472 : inline std::string toString(const typename std::vector<V*>::const_iterator& b, const typename std::vector<V*>::const_iterator& e, std::streamsize accuracy = gPrecision) {
237 : UNUSED_PARAMETER(accuracy);
238 760472 : std::ostringstream oss;
239 4075065 : for (typename std::vector<V*>::const_iterator it = b; it != e; ++it) {
240 3314593 : if (it != b) {
241 2563415 : oss << " ";
242 : }
243 6629186 : oss << Named::getIDSecure(*it);
244 : }
245 760472 : return oss.str();
246 760472 : }
247 :
248 : template <typename V>
249 : inline std::string toString(const std::list<V*>& v, std::streamsize accuracy = gPrecision) {
250 8 : return toString<V>(v.begin(), v.end(), accuracy);
251 : }
252 :
253 : template <typename V>
254 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) {
255 : UNUSED_PARAMETER(accuracy);
256 8 : std::ostringstream oss;
257 41 : for (typename std::list<V*>::const_iterator it = b; it != e; ++it) {
258 33 : if (it != b) {
259 27 : oss << " ";
260 : }
261 66 : oss << Named::getIDSecure(*it);
262 : }
263 8 : return oss.str();
264 8 : }
265 :
266 :
267 :
268 : //template <typename V>
269 : //inline std::string toString(const std::vector<V>& v, std::streamsize accuracy = gPrecision) {
270 : // return toString<V>(v.begin(), v.end(), accuracy);
271 : //}
272 : //
273 : //
274 : //template <typename V>
275 : //inline std::string toString(const typename std::vector<V>::const_iterator& b, const typename std::vector<V>::const_iterator& e, std::streamsize accuracy = gPrecision) {
276 : // UNUSED_PARAMETER(accuracy);
277 : // std::ostringstream oss;
278 : // for (typename std::vector<V>::const_iterator it = b; it != e; ++it) {
279 : // if (it != b) {
280 : // oss << " ";
281 : // }
282 : // oss << Named::getIDSecure(*it);
283 : // }
284 : // return oss.str();
285 : //}
286 :
287 :
288 : template <typename T, typename T_BETWEEN>
289 24433072 : inline std::string joinToString(const std::vector<T>& v, const T_BETWEEN& between, std::streamsize accuracy = gPrecision) {
290 24433072 : std::ostringstream oss;
291 : bool connect = false;
292 50948949 : for (typename std::vector<T>::const_iterator it = v.begin(); it != v.end(); ++it) {
293 26515877 : if (connect) {
294 4263612 : oss << toString(between, accuracy);
295 : } else {
296 : connect = true;
297 : }
298 53031754 : oss << toString(*it, accuracy);
299 : }
300 24433072 : return oss.str();
301 24433072 : }
302 :
303 :
304 : template <typename T, typename T_BETWEEN>
305 22369 : inline std::string joinToStringSorting(const std::vector<T>& v, const T_BETWEEN& between, std::streamsize accuracy = gPrecision) {
306 22369 : std::vector<T> sorted(v);
307 22369 : std::sort(sorted.begin(), sorted.end());
308 44738 : return joinToString(sorted, between, accuracy);
309 22369 : }
310 :
311 :
312 : template <typename T, typename T_BETWEEN>
313 96 : inline std::string joinNamedToStringSorting(const std::set<T*>& ns, const T_BETWEEN& between) {
314 : std::vector<std::string> ids;
315 360 : for (T* n : ns) {
316 528 : ids.push_back(Named::getIDSecure(n));
317 : }
318 192 : return joinToStringSorting(ids, between);
319 96 : }
320 :
321 : template <typename T, typename T_BETWEEN>
322 : inline std::string joinNamedToStringSorting(const std::set<T*, ComparatorIdLess>& ns, const T_BETWEEN& between) {
323 : std::vector<std::string> ids;
324 : for (T* n : ns) {
325 : ids.push_back(Named::getIDSecure(n));
326 : }
327 : return joinToStringSorting(ids, between);
328 : }
329 :
330 :
331 : template <typename T, typename C, typename T_BETWEEN>
332 3263 : inline std::string joinNamedToString(const std::set<T*, C>& ns, const T_BETWEEN& between) {
333 : std::vector<std::string> ids;
334 14329 : for (T* n : ns) {
335 22132 : ids.push_back(Named::getIDSecure(n));
336 : }
337 6526 : return joinToString(ids, between);
338 3263 : }
339 :
340 :
341 : template <typename KEY, typename VAL, typename T_BETWEEN, typename T_BETWEEN_KEYVAL>
342 : 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) {
343 : std::ostringstream oss;
344 : bool connect = false;
345 : for (typename std::map<KEY, VAL>::const_iterator it = s.begin(); it != s.end(); ++it) {
346 : if (connect) {
347 : oss << toString(between, accuracy);
348 : } else {
349 : connect = true;
350 : }
351 : oss << Named::getIDSecure(it->first) << between_keyval << toString(it->second, accuracy);
352 : }
353 : return oss.str();
354 : }
355 :
356 :
357 : template <typename V>
358 5014 : inline std::string toString(const std::set<V*>& v, std::streamsize accuracy = gPrecision) {
359 : UNUSED_PARAMETER(accuracy);
360 : std::vector<std::string> ids;
361 10294 : for (typename std::set<V*>::const_iterator it = v.begin(); it != v.end(); ++it) {
362 5280 : ids.push_back((*it)->getID());
363 : }
364 10028 : return joinToStringSorting(ids, " ");
365 5014 : }
366 :
367 :
368 : template <typename V>
369 : inline std::string toString(const std::set<V*, ComparatorNumericalIdLess>& v, std::streamsize accuracy = gPrecision) {
370 : UNUSED_PARAMETER(accuracy);
371 : std::vector<std::string> ids;
372 : for (typename std::set<V*, ComparatorNumericalIdLess>::const_iterator it = v.begin(); it != v.end(); ++it) {
373 : ids.push_back((*it)->getID());
374 : }
375 : return joinToStringSorting(ids, " ");
376 : }
377 :
378 :
379 : template <>
380 : inline std::string toString(const std::vector<int>& v, std::streamsize accuracy) {
381 168 : return joinToString(v, " ", accuracy);
382 : }
383 :
384 :
385 : template <>
386 : inline std::string toString(const std::vector<long long int>& v, std::streamsize accuracy) {
387 1791 : return joinToString(v, " ", accuracy);
388 : }
389 :
390 :
391 : template <>
392 : inline std::string toString(const std::vector<double>& v, std::streamsize accuracy) {
393 209637 : return joinToString(v, " ", accuracy);
394 : }
395 :
396 :
397 : template <typename V, typename W>
398 : inline std::string toString(const std::vector<std::pair<V, W> >& v, std::streamsize accuracy = gPrecision, const std::string& between = ";", const std::string& between2 = ",") {
399 : std::ostringstream oss;
400 : oss << std::setprecision(accuracy);
401 : bool connect = false;
402 : for (auto it : v) {
403 : if (connect) {
404 : oss << toString(between, accuracy);
405 : } else {
406 : connect = true;
407 : }
408 : oss << toString(it.first) << between2 << toString(it.second);
409 : }
410 : return oss.str();
411 : }
412 :
413 :
414 : template <typename T, typename T_BETWEEN>
415 68408 : inline std::string joinToString(const std::set<T>& s, const T_BETWEEN& between, std::streamsize accuracy = gPrecision) {
416 68408 : std::ostringstream oss;
417 : bool connect = false;
418 138104 : for (typename std::set<T>::const_iterator it = s.begin(); it != s.end(); ++it) {
419 69696 : if (connect) {
420 2596 : oss << toString(between, accuracy);
421 : } else {
422 : connect = true;
423 : }
424 139392 : oss << toString(*it, accuracy);
425 : }
426 68408 : return oss.str();
427 68408 : }
428 :
429 :
430 : template <>
431 : inline std::string toString(const std::vector<std::string>& v, std::streamsize) {
432 206775 : return joinToString(v, " ");
433 : }
434 :
435 :
436 : template <>
437 : inline std::string toString(const std::set<std::string>& v, std::streamsize) {
438 2685 : return joinToString(v, " ");
439 : }
440 :
441 :
442 : template <typename KEY, typename VAL, typename T_BETWEEN, typename T_BETWEEN_KEYVAL>
443 10 : inline std::string joinToString(const std::map<KEY, VAL>& s, const T_BETWEEN& between, const T_BETWEEN_KEYVAL& between_keyval, std::streamsize accuracy = gPrecision) {
444 10 : std::ostringstream oss;
445 : bool connect = false;
446 29 : for (typename std::map<KEY, VAL>::const_iterator it = s.begin(); it != s.end(); ++it) {
447 19 : if (connect) {
448 18 : oss << toString(between, accuracy);
449 : } else {
450 : connect = true;
451 : }
452 57 : oss << toString(it->first, accuracy) << between_keyval << toString(it->second, accuracy);
453 : }
454 10 : return oss.str();
455 10 : }
456 :
457 :
458 : template <>
459 : inline std::string toString(const Parameterised::Map& v, std::streamsize) {
460 : return joinToString(v, ", ", ":");
461 : }
462 :
463 : template <>
464 2293 : inline std::string toString(const MMVersion& v, std::streamsize) {
465 : // we only need higher accuracy on the minor version for hotfix releases
466 6879 : return toString(v.first) + "." + toString(v.second, 0);
467 : }
|