Mercurial > hg > orthanc-stone
comparison Applications/Samples/StoneSampleCommands_generated.hpp @ 527:b1377625e4ba bgo-commands-codegen
Removed ICommand and friends + fixed warnings + added missing header files in
solution (in CMakeLists.txt file)
author | Benjamin Golinvaux <bgo@osimis.io> |
---|---|
date | Sun, 17 Mar 2019 20:14:20 +0100 |
parents | |
children | 79bb0a02d1cc |
comparison
equal
deleted
inserted
replaced
522:700aa66f2f29 | 527:b1377625e4ba |
---|---|
1 /* | |
2 1 2 3 4 5 6 7 | |
3 12345678901234567890123456789012345678901234567890123456789012345678901234567890 | |
4 | |
5 Generated on 2019-03-15 10:00:48.763392 by stonegentool | |
6 | |
7 */ | |
8 #pragma once | |
9 | |
10 #include <exception> | |
11 #include <iostream> | |
12 #include <string> | |
13 #include <sstream> | |
14 #include <assert.h> | |
15 #include <memory> | |
16 #include <json/json.h> | |
17 | |
18 //#define STONEGEN_NO_CPP11 1 | |
19 | |
20 #ifdef STONEGEN_NO_CPP11 | |
21 #define StoneSmartPtr std::auto_ptr | |
22 #else | |
23 #define StoneSmartPtr std::unique_ptr | |
24 #endif | |
25 | |
26 namespace StoneSampleCommands | |
27 { | |
28 /** Throws in case of problem */ | |
29 inline void _StoneDeserializeValue(int32_t& destValue, const Json::Value& jsonValue) | |
30 { | |
31 destValue = jsonValue.asInt(); | |
32 } | |
33 | |
34 inline Json::Value _StoneSerializeValue(int32_t value) | |
35 { | |
36 Json::Value result(value); | |
37 return result; | |
38 } | |
39 | |
40 inline void _StoneDeserializeValue(Json::Value& destValue, const Json::Value& jsonValue) | |
41 { | |
42 destValue = jsonValue; | |
43 } | |
44 | |
45 inline Json::Value _StoneSerializeValue(Json::Value value) | |
46 { | |
47 return value; | |
48 } | |
49 | |
50 /** Throws in case of problem */ | |
51 inline void _StoneDeserializeValue(double& destValue, const Json::Value& jsonValue) | |
52 { | |
53 destValue = jsonValue.asDouble(); | |
54 } | |
55 | |
56 inline Json::Value _StoneSerializeValue(double value) | |
57 { | |
58 Json::Value result(value); | |
59 return result; | |
60 } | |
61 | |
62 /** Throws in case of problem */ | |
63 inline void _StoneDeserializeValue(bool& destValue, const Json::Value& jsonValue) | |
64 { | |
65 destValue = jsonValue.asBool(); | |
66 } | |
67 | |
68 inline Json::Value _StoneSerializeValue(bool value) | |
69 { | |
70 Json::Value result(value); | |
71 return result; | |
72 } | |
73 | |
74 /** Throws in case of problem */ | |
75 inline void _StoneDeserializeValue( | |
76 std::string& destValue | |
77 , const Json::Value& jsonValue) | |
78 { | |
79 destValue = jsonValue.asString(); | |
80 } | |
81 | |
82 inline Json::Value _StoneSerializeValue(const std::string& value) | |
83 { | |
84 // the following is better than | |
85 Json::Value result(value.data(),value.data()+value.size()); | |
86 return result; | |
87 } | |
88 | |
89 inline std::string MakeIndent(int indent) | |
90 { | |
91 char* txt = reinterpret_cast<char*>(malloc(indent+1)); // NO EXCEPTION BELOW!!!!!!!!!!!! | |
92 for(size_t i = 0; i < indent; ++i) | |
93 txt[i] = ' '; | |
94 txt[indent] = 0; | |
95 std::string retVal(txt); | |
96 free(txt); // NO EXCEPTION ABOVE !!!!!!!!!! | |
97 return retVal; | |
98 } | |
99 | |
100 // generic dumper | |
101 template<typename T> | |
102 std::ostream& StoneDumpValue(std::ostream& out, const T& value, int indent) | |
103 { | |
104 out << MakeIndent(indent) << value; | |
105 return out; | |
106 } | |
107 | |
108 // string dumper | |
109 inline std::ostream& StoneDumpValue(std::ostream& out, const std::string& value, int indent) | |
110 { | |
111 out << MakeIndent(indent) << "\"" << value << "\""; | |
112 return out; | |
113 } | |
114 | |
115 /** Throws in case of problem */ | |
116 template<typename T> | |
117 void _StoneDeserializeValue( | |
118 std::map<std::string, T>& destValue, const Json::Value& jsonValue) | |
119 { | |
120 destValue.clear(); | |
121 for ( | |
122 Json::Value::const_iterator itr = jsonValue.begin(); | |
123 itr != jsonValue.end(); | |
124 itr++) | |
125 { | |
126 std::string key; | |
127 _StoneDeserializeValue(key, itr.key()); | |
128 | |
129 T innerDestValue; | |
130 _StoneDeserializeValue(innerDestValue, *itr); | |
131 | |
132 destValue[key] = innerDestValue; | |
133 } | |
134 } | |
135 | |
136 template<typename T> | |
137 Json::Value _StoneSerializeValue(const std::map<std::string,T>& value) | |
138 { | |
139 Json::Value result(Json::objectValue); | |
140 | |
141 for (typename std::map<std::string, T>::const_iterator it = value.cbegin(); | |
142 it != value.cend(); ++it) | |
143 { | |
144 // it->first it->second | |
145 result[it->first] = _StoneSerializeValue(it->second); | |
146 } | |
147 return result; | |
148 } | |
149 | |
150 template<typename T> | |
151 std::ostream& StoneDumpValue(std::ostream& out, const std::map<std::string,T>& value, int indent) | |
152 { | |
153 out << MakeIndent(indent) << "{\n"; | |
154 for (typename std::map<std::string, T>::const_iterator it = value.cbegin(); | |
155 it != value.cend(); ++it) | |
156 { | |
157 out << MakeIndent(indent+2) << "\"" << it->first << "\" : "; | |
158 StoneDumpValue(out, it->second, indent+2); | |
159 } | |
160 out << MakeIndent(indent) << "}\n"; | |
161 return out; | |
162 } | |
163 | |
164 /** Throws in case of problem */ | |
165 template<typename T> | |
166 void _StoneDeserializeValue( | |
167 std::vector<T>& destValue, const Json::Value& jsonValue) | |
168 { | |
169 destValue.clear(); | |
170 destValue.reserve(jsonValue.size()); | |
171 for (Json::Value::ArrayIndex i = 0; i != jsonValue.size(); i++) | |
172 { | |
173 T innerDestValue; | |
174 _StoneDeserializeValue(innerDestValue, jsonValue[i]); | |
175 destValue.push_back(innerDestValue); | |
176 } | |
177 } | |
178 | |
179 template<typename T> | |
180 Json::Value _StoneSerializeValue(const std::vector<T>& value) | |
181 { | |
182 Json::Value result(Json::arrayValue); | |
183 for (size_t i = 0; i < value.size(); ++i) | |
184 { | |
185 result.append(_StoneSerializeValue(value[i])); | |
186 } | |
187 return result; | |
188 } | |
189 | |
190 template<typename T> | |
191 std::ostream& StoneDumpValue(std::ostream& out, const std::vector<T>& value, int indent) | |
192 { | |
193 out << MakeIndent(indent) << "[\n"; | |
194 for (size_t i = 0; i < value.size(); ++i) | |
195 { | |
196 StoneDumpValue(out, value[i], indent+2); | |
197 } | |
198 out << MakeIndent(indent) << "]\n"; | |
199 return out; | |
200 } | |
201 | |
202 inline void StoneCheckSerializedValueTypeGeneric(const Json::Value& value) | |
203 { | |
204 if ((!value.isMember("type")) || (!value["type"].isString())) | |
205 { | |
206 std::stringstream ss; | |
207 ss << "Cannot deserialize value ('type' key invalid)"; | |
208 throw std::runtime_error(ss.str()); | |
209 } | |
210 } | |
211 | |
212 inline void StoneCheckSerializedValueType( | |
213 const Json::Value& value, std::string typeStr) | |
214 { | |
215 StoneCheckSerializedValueTypeGeneric(value); | |
216 | |
217 std::string actTypeStr = value["type"].asString(); | |
218 if (actTypeStr != typeStr) | |
219 { | |
220 std::stringstream ss; | |
221 ss << "Cannot deserialize type" << actTypeStr | |
222 << "into " << typeStr; | |
223 throw std::runtime_error(ss.str()); | |
224 } | |
225 } | |
226 | |
227 // end of generic methods | |
228 | |
229 // end of generic methods | |
230 | |
231 enum Tool { | |
232 Tool_LineMeasure, | |
233 Tool_CircleMeasure, | |
234 Tool_Crop, | |
235 Tool_Windowing, | |
236 Tool_Zoom, | |
237 Tool_Pan, | |
238 Tool_Move, | |
239 Tool_Rotate, | |
240 Tool_Resize, | |
241 Tool_Mask, | |
242 }; | |
243 | |
244 inline std::string ToString(const Tool& value) | |
245 { | |
246 if( value == Tool_LineMeasure) | |
247 { | |
248 return std::string("LineMeasure"); | |
249 } | |
250 if( value == Tool_CircleMeasure) | |
251 { | |
252 return std::string("CircleMeasure"); | |
253 } | |
254 if( value == Tool_Crop) | |
255 { | |
256 return std::string("Crop"); | |
257 } | |
258 if( value == Tool_Windowing) | |
259 { | |
260 return std::string("Windowing"); | |
261 } | |
262 if( value == Tool_Zoom) | |
263 { | |
264 return std::string("Zoom"); | |
265 } | |
266 if( value == Tool_Pan) | |
267 { | |
268 return std::string("Pan"); | |
269 } | |
270 if( value == Tool_Move) | |
271 { | |
272 return std::string("Move"); | |
273 } | |
274 if( value == Tool_Rotate) | |
275 { | |
276 return std::string("Rotate"); | |
277 } | |
278 if( value == Tool_Resize) | |
279 { | |
280 return std::string("Resize"); | |
281 } | |
282 if( value == Tool_Mask) | |
283 { | |
284 return std::string("Mask"); | |
285 } | |
286 std::stringstream ss; | |
287 ss << "Value \"" << value << "\" cannot be converted to Tool. Possible values are: " | |
288 << " LineMeasure = " << static_cast<int64_t>(Tool_LineMeasure) << ", " | |
289 << " CircleMeasure = " << static_cast<int64_t>(Tool_CircleMeasure) << ", " | |
290 << " Crop = " << static_cast<int64_t>(Tool_Crop) << ", " | |
291 << " Windowing = " << static_cast<int64_t>(Tool_Windowing) << ", " | |
292 << " Zoom = " << static_cast<int64_t>(Tool_Zoom) << ", " | |
293 << " Pan = " << static_cast<int64_t>(Tool_Pan) << ", " | |
294 << " Move = " << static_cast<int64_t>(Tool_Move) << ", " | |
295 << " Rotate = " << static_cast<int64_t>(Tool_Rotate) << ", " | |
296 << " Resize = " << static_cast<int64_t>(Tool_Resize) << ", " | |
297 << " Mask = " << static_cast<int64_t>(Tool_Mask) << ", " | |
298 << std::endl; | |
299 std::string msg = ss.str(); | |
300 throw std::runtime_error(msg); | |
301 } | |
302 | |
303 inline void FromString(Tool& value, std::string strValue) | |
304 { | |
305 if( strValue == std::string("LineMeasure") ) | |
306 { | |
307 value = Tool_LineMeasure; | |
308 return; | |
309 } | |
310 if( strValue == std::string("CircleMeasure") ) | |
311 { | |
312 value = Tool_CircleMeasure; | |
313 return; | |
314 } | |
315 if( strValue == std::string("Crop") ) | |
316 { | |
317 value = Tool_Crop; | |
318 return; | |
319 } | |
320 if( strValue == std::string("Windowing") ) | |
321 { | |
322 value = Tool_Windowing; | |
323 return; | |
324 } | |
325 if( strValue == std::string("Zoom") ) | |
326 { | |
327 value = Tool_Zoom; | |
328 return; | |
329 } | |
330 if( strValue == std::string("Pan") ) | |
331 { | |
332 value = Tool_Pan; | |
333 return; | |
334 } | |
335 if( strValue == std::string("Move") ) | |
336 { | |
337 value = Tool_Move; | |
338 return; | |
339 } | |
340 if( strValue == std::string("Rotate") ) | |
341 { | |
342 value = Tool_Rotate; | |
343 return; | |
344 } | |
345 if( strValue == std::string("Resize") ) | |
346 { | |
347 value = Tool_Resize; | |
348 return; | |
349 } | |
350 if( strValue == std::string("Mask") ) | |
351 { | |
352 value = Tool_Mask; | |
353 return; | |
354 } | |
355 | |
356 std::stringstream ss; | |
357 ss << "String \"" << strValue << "\" cannot be converted to Tool. Possible values are: LineMeasure CircleMeasure Crop Windowing Zoom Pan Move Rotate Resize Mask "; | |
358 std::string msg = ss.str(); | |
359 throw std::runtime_error(msg); | |
360 } | |
361 | |
362 | |
363 inline void _StoneDeserializeValue( | |
364 Tool& destValue, const Json::Value& jsonValue) | |
365 { | |
366 FromString(destValue, jsonValue.asString()); | |
367 } | |
368 | |
369 inline Json::Value _StoneSerializeValue(const Tool& value) | |
370 { | |
371 std::string strValue = ToString(value); | |
372 return Json::Value(strValue); | |
373 } | |
374 | |
375 inline std::ostream& StoneDumpValue(std::ostream& out, const Tool& value, int indent = 0) | |
376 { | |
377 if( value == Tool_LineMeasure) | |
378 { | |
379 out << MakeIndent(indent) << "LineMeasure" << std::endl; | |
380 } | |
381 if( value == Tool_CircleMeasure) | |
382 { | |
383 out << MakeIndent(indent) << "CircleMeasure" << std::endl; | |
384 } | |
385 if( value == Tool_Crop) | |
386 { | |
387 out << MakeIndent(indent) << "Crop" << std::endl; | |
388 } | |
389 if( value == Tool_Windowing) | |
390 { | |
391 out << MakeIndent(indent) << "Windowing" << std::endl; | |
392 } | |
393 if( value == Tool_Zoom) | |
394 { | |
395 out << MakeIndent(indent) << "Zoom" << std::endl; | |
396 } | |
397 if( value == Tool_Pan) | |
398 { | |
399 out << MakeIndent(indent) << "Pan" << std::endl; | |
400 } | |
401 if( value == Tool_Move) | |
402 { | |
403 out << MakeIndent(indent) << "Move" << std::endl; | |
404 } | |
405 if( value == Tool_Rotate) | |
406 { | |
407 out << MakeIndent(indent) << "Rotate" << std::endl; | |
408 } | |
409 if( value == Tool_Resize) | |
410 { | |
411 out << MakeIndent(indent) << "Resize" << std::endl; | |
412 } | |
413 if( value == Tool_Mask) | |
414 { | |
415 out << MakeIndent(indent) << "Mask" << std::endl; | |
416 } | |
417 return out; | |
418 } | |
419 | |
420 | |
421 enum ActionType { | |
422 ActionType_UndoCrop, | |
423 ActionType_Rotate, | |
424 ActionType_Invert, | |
425 }; | |
426 | |
427 inline std::string ToString(const ActionType& value) | |
428 { | |
429 if( value == ActionType_UndoCrop) | |
430 { | |
431 return std::string("UndoCrop"); | |
432 } | |
433 if( value == ActionType_Rotate) | |
434 { | |
435 return std::string("Rotate"); | |
436 } | |
437 if( value == ActionType_Invert) | |
438 { | |
439 return std::string("Invert"); | |
440 } | |
441 std::stringstream ss; | |
442 ss << "Value \"" << value << "\" cannot be converted to ActionType. Possible values are: " | |
443 << " UndoCrop = " << static_cast<int64_t>(ActionType_UndoCrop) << ", " | |
444 << " Rotate = " << static_cast<int64_t>(ActionType_Rotate) << ", " | |
445 << " Invert = " << static_cast<int64_t>(ActionType_Invert) << ", " | |
446 << std::endl; | |
447 std::string msg = ss.str(); | |
448 throw std::runtime_error(msg); | |
449 } | |
450 | |
451 inline void FromString(ActionType& value, std::string strValue) | |
452 { | |
453 if( strValue == std::string("UndoCrop") ) | |
454 { | |
455 value = ActionType_UndoCrop; | |
456 return; | |
457 } | |
458 if( strValue == std::string("Rotate") ) | |
459 { | |
460 value = ActionType_Rotate; | |
461 return; | |
462 } | |
463 if( strValue == std::string("Invert") ) | |
464 { | |
465 value = ActionType_Invert; | |
466 return; | |
467 } | |
468 | |
469 std::stringstream ss; | |
470 ss << "String \"" << strValue << "\" cannot be converted to ActionType. Possible values are: UndoCrop Rotate Invert "; | |
471 std::string msg = ss.str(); | |
472 throw std::runtime_error(msg); | |
473 } | |
474 | |
475 | |
476 inline void _StoneDeserializeValue( | |
477 ActionType& destValue, const Json::Value& jsonValue) | |
478 { | |
479 FromString(destValue, jsonValue.asString()); | |
480 } | |
481 | |
482 inline Json::Value _StoneSerializeValue(const ActionType& value) | |
483 { | |
484 std::string strValue = ToString(value); | |
485 return Json::Value(strValue); | |
486 } | |
487 | |
488 inline std::ostream& StoneDumpValue(std::ostream& out, const ActionType& value, int indent = 0) | |
489 { | |
490 if( value == ActionType_UndoCrop) | |
491 { | |
492 out << MakeIndent(indent) << "UndoCrop" << std::endl; | |
493 } | |
494 if( value == ActionType_Rotate) | |
495 { | |
496 out << MakeIndent(indent) << "Rotate" << std::endl; | |
497 } | |
498 if( value == ActionType_Invert) | |
499 { | |
500 out << MakeIndent(indent) << "Invert" << std::endl; | |
501 } | |
502 return out; | |
503 } | |
504 | |
505 | |
506 | |
507 #ifdef _MSC_VER | |
508 #pragma region SelectTool | |
509 #endif //_MSC_VER | |
510 | |
511 struct SelectTool | |
512 { | |
513 Tool tool; | |
514 | |
515 SelectTool(Tool tool = Tool()) | |
516 { | |
517 this->tool = tool; | |
518 } | |
519 }; | |
520 | |
521 inline void _StoneDeserializeValue(SelectTool& destValue, const Json::Value& value) | |
522 { | |
523 _StoneDeserializeValue(destValue.tool, value["tool"]); | |
524 } | |
525 | |
526 inline Json::Value _StoneSerializeValue(const SelectTool& value) | |
527 { | |
528 Json::Value result(Json::objectValue); | |
529 result["tool"] = _StoneSerializeValue(value.tool); | |
530 | |
531 return result; | |
532 } | |
533 | |
534 inline std::ostream& StoneDumpValue(std::ostream& out, const SelectTool& value, int indent = 0) | |
535 { | |
536 out << MakeIndent(indent) << "{\n"; | |
537 out << MakeIndent(indent) << "tool:\n"; | |
538 StoneDumpValue(out, value.tool,indent+2); | |
539 out << "\n"; | |
540 | |
541 out << MakeIndent(indent) << "}\n"; | |
542 return out; | |
543 } | |
544 | |
545 inline void StoneDeserialize(SelectTool& destValue, const Json::Value& value) | |
546 { | |
547 StoneCheckSerializedValueType(value, "StoneSampleCommands.SelectTool"); | |
548 _StoneDeserializeValue(destValue, value["value"]); | |
549 } | |
550 | |
551 inline Json::Value StoneSerializeToJson(const SelectTool& value) | |
552 { | |
553 Json::Value result(Json::objectValue); | |
554 result["type"] = "StoneSampleCommands.SelectTool"; | |
555 result["value"] = _StoneSerializeValue(value); | |
556 return result; | |
557 } | |
558 | |
559 inline std::string StoneSerialize(const SelectTool& value) | |
560 { | |
561 Json::Value resultJson = StoneSerializeToJson(value); | |
562 std::string resultStr = resultJson.toStyledString(); | |
563 return resultStr; | |
564 } | |
565 | |
566 #ifdef _MSC_VER | |
567 #pragma endregion SelectTool | |
568 #endif //_MSC_VER | |
569 | |
570 #ifdef _MSC_VER | |
571 #pragma region Action | |
572 #endif //_MSC_VER | |
573 | |
574 struct Action | |
575 { | |
576 ActionType type; | |
577 | |
578 Action(ActionType type = ActionType()) | |
579 { | |
580 this->type = type; | |
581 } | |
582 }; | |
583 | |
584 inline void _StoneDeserializeValue(Action& destValue, const Json::Value& value) | |
585 { | |
586 _StoneDeserializeValue(destValue.type, value["type"]); | |
587 } | |
588 | |
589 inline Json::Value _StoneSerializeValue(const Action& value) | |
590 { | |
591 Json::Value result(Json::objectValue); | |
592 result["type"] = _StoneSerializeValue(value.type); | |
593 | |
594 return result; | |
595 } | |
596 | |
597 inline std::ostream& StoneDumpValue(std::ostream& out, const Action& value, int indent = 0) | |
598 { | |
599 out << MakeIndent(indent) << "{\n"; | |
600 out << MakeIndent(indent) << "type:\n"; | |
601 StoneDumpValue(out, value.type,indent+2); | |
602 out << "\n"; | |
603 | |
604 out << MakeIndent(indent) << "}\n"; | |
605 return out; | |
606 } | |
607 | |
608 inline void StoneDeserialize(Action& destValue, const Json::Value& value) | |
609 { | |
610 StoneCheckSerializedValueType(value, "StoneSampleCommands.Action"); | |
611 _StoneDeserializeValue(destValue, value["value"]); | |
612 } | |
613 | |
614 inline Json::Value StoneSerializeToJson(const Action& value) | |
615 { | |
616 Json::Value result(Json::objectValue); | |
617 result["type"] = "StoneSampleCommands.Action"; | |
618 result["value"] = _StoneSerializeValue(value); | |
619 return result; | |
620 } | |
621 | |
622 inline std::string StoneSerialize(const Action& value) | |
623 { | |
624 Json::Value resultJson = StoneSerializeToJson(value); | |
625 std::string resultStr = resultJson.toStyledString(); | |
626 return resultStr; | |
627 } | |
628 | |
629 #ifdef _MSC_VER | |
630 #pragma endregion Action | |
631 #endif //_MSC_VER | |
632 | |
633 #ifdef _MSC_VER | |
634 #pragma region Dispatching code | |
635 #endif //_MSC_VER | |
636 | |
637 class IHandler | |
638 { | |
639 public: | |
640 virtual bool Handle(const SelectTool& value) = 0; | |
641 }; | |
642 | |
643 /** Service function for StoneDispatchToHandler */ | |
644 inline bool StoneDispatchJsonToHandler( | |
645 const Json::Value& jsonValue, IHandler* handler) | |
646 { | |
647 StoneCheckSerializedValueTypeGeneric(jsonValue); | |
648 std::string type = jsonValue["type"].asString(); | |
649 if (type == "") | |
650 { | |
651 // this should never ever happen | |
652 throw std::runtime_error("Caught empty type while dispatching"); | |
653 } | |
654 else if (type == "StoneSampleCommands.SelectTool") | |
655 { | |
656 SelectTool value; | |
657 _StoneDeserializeValue(value, jsonValue["value"]); | |
658 return handler->Handle(value); | |
659 } | |
660 else | |
661 { | |
662 return false; | |
663 } | |
664 } | |
665 | |
666 /** Takes a serialized type and passes this to the handler */ | |
667 inline bool StoneDispatchToHandler(std::string strValue, IHandler* handler) | |
668 { | |
669 Json::Value readValue; | |
670 | |
671 Json::CharReaderBuilder builder; | |
672 Json::CharReader* reader = builder.newCharReader(); | |
673 | |
674 StoneSmartPtr<Json::CharReader> ptr(reader); | |
675 | |
676 std::string errors; | |
677 | |
678 bool ok = reader->parse( | |
679 strValue.c_str(), | |
680 strValue.c_str() + strValue.size(), | |
681 &readValue, | |
682 &errors | |
683 ); | |
684 if (!ok) | |
685 { | |
686 std::stringstream ss; | |
687 ss << "Jsoncpp parsing error: " << errors; | |
688 throw std::runtime_error(ss.str()); | |
689 } | |
690 return StoneDispatchJsonToHandler(readValue, handler); | |
691 } | |
692 | |
693 #ifdef _MSC_VER | |
694 #pragma endregion Dispatching code | |
695 #endif //_MSC_VER | |
696 } |