Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2002-2025 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 128378529 : inline std::string toString(const T& t, std::streamsize accuracy = gPrecision) {
47 128378529 : std::ostringstream oss;
48 : oss.setf(std::ios::fixed, std::ios::floatfield);
49 128378529 : oss << std::setprecision(accuracy);
50 107167354 : oss << t;
51 128378529 : return oss.str();
52 128378529 : }
53 :
54 :
55 : template<typename T>
56 2576 : 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 2576 : std::stringstream stream;
59 5152 : stream << "0x" << std::setfill('0') << std::setw(numDigits == 0 ? sizeof(T) * 2 : numDigits) << std::hex << i;
60 2576 : return stream.str();
61 2576 : }
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 24385491 : inline std::string toString<SumoXMLTag>(const SumoXMLTag& tag, std::streamsize accuracy) {
72 : UNUSED_PARAMETER(accuracy);
73 24385491 : return SUMOXMLDefinitions::Tags.getString(tag);
74 : }
75 :
76 :
77 : template <>
78 72035833 : inline std::string toString<SumoXMLAttr>(const SumoXMLAttr& attr, std::streamsize accuracy) {
79 : UNUSED_PARAMETER(accuracy);
80 72035833 : return SUMOXMLDefinitions::Attrs.getString(attr);
81 : }
82 :
83 :
84 : template <>
85 74454 : inline std::string toString<SumoXMLNodeType>(const SumoXMLNodeType& nodeType, std::streamsize accuracy) {
86 : UNUSED_PARAMETER(accuracy);
87 74454 : return SUMOXMLDefinitions::NodeTypes.getString(nodeType);
88 : }
89 :
90 :
91 : template <>
92 105337 : inline std::string toString<SumoXMLEdgeFunc>(const SumoXMLEdgeFunc& edgeFunc, std::streamsize accuracy) {
93 : UNUSED_PARAMETER(accuracy);
94 105337 : return SUMOXMLDefinitions::EdgeFunctions.getString(edgeFunc);
95 : }
96 :
97 :
98 : template <>
99 1894 : inline std::string toString<SUMOVehicleClass>(const SUMOVehicleClass& vClass, std::streamsize accuracy) {
100 : UNUSED_PARAMETER(accuracy);
101 1894 : return SumoVehicleClassStrings.getString(vClass);
102 : }
103 :
104 :
105 : template <>
106 73012 : inline std::string toString<LaneSpreadFunction>(const LaneSpreadFunction& lsf, std::streamsize accuracy) {
107 : UNUSED_PARAMETER(accuracy);
108 73012 : return SUMOXMLDefinitions::LaneSpreadFunctions.getString(lsf);
109 : }
110 :
111 : template <>
112 11795 : inline std::string toString<ParkingType>(const ParkingType& pt, std::streamsize accuracy) {
113 : UNUSED_PARAMETER(accuracy);
114 11795 : return SUMOXMLDefinitions::ParkingTypes.getString(pt);
115 : }
116 :
117 : template <>
118 32 : inline std::string toString<RightOfWay>(const RightOfWay& row, std::streamsize accuracy) {
119 : UNUSED_PARAMETER(accuracy);
120 32 : return SUMOXMLDefinitions::RightOfWayValues.getString(row);
121 : }
122 :
123 : template <>
124 325 : inline std::string toString<FringeType>(const FringeType& fringeType, std::streamsize accuracy) {
125 : UNUSED_PARAMETER(accuracy);
126 325 : 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 201534 : inline std::string toString<LinkState>(const LinkState& linkState, std::streamsize accuracy) {
143 : UNUSED_PARAMETER(accuracy);
144 201534 : return SUMOXMLDefinitions::LinkStates.getString(linkState);
145 : }
146 :
147 :
148 : template <>
149 607560 : inline std::string toString<LinkDirection>(const LinkDirection& linkDir, std::streamsize accuracy) {
150 : UNUSED_PARAMETER(accuracy);
151 607560 : return SUMOXMLDefinitions::LinkDirections.getString(linkDir);
152 : }
153 :
154 :
155 : template <>
156 2431 : inline std::string toString<TrafficLightType>(const TrafficLightType& type, std::streamsize accuracy) {
157 : UNUSED_PARAMETER(accuracy);
158 2431 : 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 16120 : inline std::string toString<LaneChangeAction>(const LaneChangeAction& action, std::streamsize accuracy) {
207 : UNUSED_PARAMETER(accuracy);
208 16120 : std::vector<std::string> strings = SUMOXMLDefinitions::LaneChangeActions.getStrings();
209 : bool hadOne = false;
210 16120 : std::ostringstream oss;
211 322400 : for (std::vector<std::string>::const_iterator it = strings.begin(); it != strings.end(); ++it) {
212 306280 : if ((action & SUMOXMLDefinitions::LaneChangeActions.get(*it)) != 0) {
213 24531 : if (hadOne) {
214 8415 : oss << "|";
215 : } else {
216 : hadOne = true;
217 : }
218 : oss << (*it);
219 : }
220 : }
221 16120 : return oss.str();
222 16120 : }
223 :
224 : template <>
225 : inline std::string toString<Distribution_Parameterized>(const Distribution_Parameterized& dist, std::streamsize accuracy) {
226 462 : 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 750322 : return toString<V>(v.begin(), v.end(), accuracy);
232 : }
233 :
234 :
235 : template <typename V>
236 751658 : 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 751658 : std::ostringstream oss;
239 3989802 : for (typename std::vector<V*>::const_iterator it = b; it != e; ++it) {
240 3238144 : if (it != b) {
241 2494783 : oss << " ";
242 : }
243 6476288 : oss << Named::getIDSecure(*it);
244 : }
245 751658 : return oss.str();
246 751658 : }
247 :
248 : template <typename V>
249 : inline std::string toString(const std::list<V*>& v, std::streamsize accuracy = gPrecision) {
250 7 : return toString<V>(v.begin(), v.end(), accuracy);
251 : }
252 :
253 : template <typename V>
254 7 : 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 7 : std::ostringstream oss;
257 39 : for (typename std::list<V*>::const_iterator it = b; it != e; ++it) {
258 32 : if (it != b) {
259 26 : oss << " ";
260 : }
261 64 : oss << Named::getIDSecure(*it);
262 : }
263 7 : return oss.str();
264 7 : }
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 15797368 : inline std::string joinToString(const std::vector<T>& v, const T_BETWEEN& between, std::streamsize accuracy = gPrecision) {
290 15797368 : std::ostringstream oss;
291 : bool connect = false;
292 33448649 : for (typename std::vector<T>::const_iterator it = v.begin(); it != v.end(); ++it) {
293 17651281 : if (connect) {
294 3803480 : oss << toString(between, accuracy);
295 : } else {
296 : connect = true;
297 : }
298 35302562 : oss << toString(*it, accuracy);
299 : }
300 15797368 : return oss.str();
301 15797368 : }
302 :
303 :
304 : template <typename T, typename T_BETWEEN>
305 20710 : inline std::string joinToStringSorting(const std::vector<T>& v, const T_BETWEEN& between, std::streamsize accuracy = gPrecision) {
306 20710 : std::vector<T> sorted(v);
307 20710 : std::sort(sorted.begin(), sorted.end());
308 41420 : return joinToString(sorted, between, accuracy);
309 20710 : }
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 3262 : inline std::string joinNamedToString(const std::set<T*, C>& ns, const T_BETWEEN& between) {
333 : std::vector<std::string> ids;
334 14309 : for (T* n : ns) {
335 22094 : ids.push_back(Named::getIDSecure(n));
336 : }
337 6524 : return joinToString(ids, between);
338 3262 : }
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 5058 : inline std::string toString(const std::set<V*>& v, std::streamsize accuracy = gPrecision) {
359 : UNUSED_PARAMETER(accuracy);
360 : std::vector<std::string> ids;
361 10378 : for (typename std::set<V*>::const_iterator it = v.begin(); it != v.end(); ++it) {
362 5320 : ids.push_back((*it)->getID());
363 : }
364 10116 : return joinToStringSorting(ids, " ");
365 5058 : }
366 :
367 :
368 : template <>
369 : inline std::string toString(const std::vector<int>& v, std::streamsize accuracy) {
370 168 : return joinToString(v, " ", accuracy);
371 : }
372 :
373 :
374 : template <>
375 : inline std::string toString(const std::vector<long long int>& v, std::streamsize accuracy) {
376 1791 : return joinToString(v, " ", accuracy);
377 : }
378 :
379 :
380 : template <>
381 : inline std::string toString(const std::vector<double>& v, std::streamsize accuracy) {
382 209639 : return joinToString(v, " ", accuracy);
383 : }
384 :
385 :
386 : template <typename V, typename W>
387 : inline std::string toString(const std::vector<std::pair<V, W> >& v, std::streamsize accuracy = gPrecision, const std::string& between = ";", const std::string& between2 = ",") {
388 : std::ostringstream oss;
389 : oss << std::setprecision(accuracy);
390 : bool connect = false;
391 : for (auto it : v) {
392 : if (connect) {
393 : oss << toString(between, accuracy);
394 : } else {
395 : connect = true;
396 : }
397 : oss << toString(it.first) << between2 << toString(it.second);
398 : }
399 : return oss.str();
400 : }
401 :
402 :
403 : template <typename T, typename T_BETWEEN>
404 3928 : inline std::string joinToString(const std::set<T>& s, const T_BETWEEN& between, std::streamsize accuracy = gPrecision) {
405 3928 : std::ostringstream oss;
406 : bool connect = false;
407 9057 : for (typename std::set<T>::const_iterator it = s.begin(); it != s.end(); ++it) {
408 5129 : if (connect) {
409 2422 : oss << toString(between, accuracy);
410 : } else {
411 : connect = true;
412 : }
413 10258 : oss << toString(*it, accuracy);
414 : }
415 3928 : return oss.str();
416 3928 : }
417 :
418 :
419 : template <>
420 : inline std::string toString(const std::vector<std::string>& v, std::streamsize) {
421 185275 : return joinToString(v, " ");
422 : }
423 :
424 :
425 : template <>
426 : inline std::string toString(const std::set<std::string>& v, std::streamsize) {
427 2235 : return joinToString(v, " ");
428 : }
429 :
430 :
431 : template <typename KEY, typename VAL, typename T_BETWEEN, typename T_BETWEEN_KEYVAL>
432 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) {
433 10 : std::ostringstream oss;
434 : bool connect = false;
435 30 : for (typename std::map<KEY, VAL>::const_iterator it = s.begin(); it != s.end(); ++it) {
436 20 : if (connect) {
437 20 : oss << toString(between, accuracy);
438 : } else {
439 : connect = true;
440 : }
441 60 : oss << toString(it->first, accuracy) << between_keyval << toString(it->second, accuracy);
442 : }
443 10 : return oss.str();
444 10 : }
445 :
446 :
447 : template <>
448 : inline std::string toString(const Parameterised::Map& v, std::streamsize) {
449 : return joinToString(v, ", ", ":");
450 : }
451 :
452 : template <>
453 2266 : inline std::string toString(const MMVersion& v, std::streamsize) {
454 : // we only need higher accuracy on the minor version for hotfix releases
455 6798 : return toString(v.first) + "." + toString(v.second, 0);
456 : }
|