API Documentation
Loading...
Searching...
No Matches
StringStream.h
Go to the documentation of this file.
1/*--------------------------------------------------------------------------------------------
2Copyright (c) 2019, NDEVR LLC
3tyler.parke@ndevr.org
4 __ __ ____ _____ __ __ _______
5 | \ | | | __ \ | ___|\ \ / / | __ \
6 | \ | | | | \ \ | |___ \ \ / / | |__) |
7 | . \| | | |__/ / | |___ \ V / | _ /
8 | |\ |_|_____/__|_____|___\_/____| | \ \
9 |__| \__________________________________| \__\
10
11Subject to the terms of the Enterprise+ Agreement, NDEVR hereby grants
12Licensee a limited, non-exclusive, non-transferable, royalty-free license
13(without the right to sublicense) to use the API solely for the purpose of
14Licensee's internal development efforts to develop applications for which
15the API was provided.
16
17The above copyright notice and this permission notice shall be included in all
18copies or substantial portions of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
21INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
22PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
23FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25DEALINGS IN THE SOFTWARE.
26
27Library: Base
28File: StringStream
29Included in API: True
30Author(s): Tyler Parke
31 *-----------------------------------------------------------------------------------------**/
32#pragma once
33#include <NDEVR/Vector.h>
34#include <NDEVR/Bounds.h>
35#include <NDEVR/NumberParser.h>
36#include <NDEVR/ObjectInfo.h>
37#include <NDEVR/Buffer.h>
38#include "Matrix.hpp"
39#include <string>
40#if _MSC_VER
41#pragma warning( disable : 4661)
42#endif
43namespace NDEVR
44{
45 class TypeInfo;
46 class String;
47 class TranslatedString;
48 /**--------------------------------------------------------------------------------------------------
49 \brief Logic for splitting a string into two.
50 **/
52 {
53 public:
54 static const char* begin(const String& s);
55 static const char* end(const String& s);
57 };
58 /**--------------------------------------------------------------------------------------------------
59 \brief Logic for creating a regex for a given type of data
60 **/
62 {
63 public:
64 static const char* ValidRegex(const TypeInfo& info);
65 };
66
67 /**--------------------------------------------------------------------------------------------------
68 \brief Logic for reading or writing to a string or a user friendly, TranslatedString
69
70 For example, to implement a given class or enum so that it can be cast to and from a string, or as a
71 displayed to the end-user, you might add something similar to a CPP file.
72
73 Example Code For automatic conversion from another string class:
74 \code
75 template<> void StringStream<QString>::fromString(const String& string, QString& value)
76 {
77 if (string.size() > 0)
78 value = QString::fromUtf8(string.c_str());
79 else
80 value.clear();
81 }
82 template<> void StringStream<QString>::toString(const QString& value, String& string)
83 {
84 string.addAll(value.toUtf8().constData());
85 }
86 //No need to override toDisplayString as no custom way to show this data to the user
87 \endcode
88 Example Code For automatic conversion from a non-trivial structure
89 \code
90 template<> void StringStream<KeyEvent>::fromString(const String& string, KeyEvent& value)
91 {
92 if (string.size() == 0)
93 value = KeyEvent();
94 else
95 {
96 Buffer<String> parts = string.splitString(cast<char>(29));
97 if (parts.size() == 3)
98 {
99 value.key_type = cast<KeyEvent::KEY>(parts[0].getAs<uint04>());
100 value.key_modifier = parts[1].getAs<uint01>();
101 value.event_type = cast<KeyEvent::KeyEentType>(parts[2].getAs<uint04>());
102 }
103 }
104 }
105 template<> void StringStream<KeyEvent>::toString(const KeyEvent& value, String& string)
106 {
107 StringStream<uint04>::toString(cast<uint04>(value.key_type), string);
108 string += cast<char>(29);
109 StringStream<uint01>::toString(value.key_modifier, string);
110 string += cast<char>(29);
111 StringStream<uint04>::toString(cast<uint04>(value.event_type), string);
112 }
113 template<> void StringStream<KeyEvent>::toDisplayString(const KeyEvent& value, TranslatedString& translated_string)
114 {
115 String string;
116 if (value.key_modifier & KeyEvent::SHIFT && value.key_type != KeyEvent::LIB_VK_SHIFT)
117 string += _t("SHIFT").translation()+"+";
118 if (value.key_modifier & KeyEvent::CTRL && value.key_type != KeyEvent::LIB_VK_RCONTROL && value.key_type != KeyEvent::LIB_VK_LCONTROL)
119 string += _t("CTRL").translation() + "+";
120 if (value.key_modifier & KeyEvent::FUNCTION)
121 string += _t("FUNCTION").translation() + "+";
122 if (value.key_modifier & KeyEvent::ALT && value.key_type != KeyEvent::LIB_VK_MENU)
123 string += _t("ALT").translation() + "+";
124 char char_val = value.toChar();
125 switch(char_val)
126 {
127 case '\n':
128 case ' ':
129 {
130 switch (value.key_type)
131 {
132 case KeyEvent::VK_KEY_F1: string += "F1"; break;
133 case KeyEvent::VK_KEY_F2: string += "F2"; break;
134 case KeyEvent::VK_KEY_F3: string += "F3"; break;
135 case KeyEvent::VK_KEY_F4: string += "F4"; break;
136 case KeyEvent::VK_KEY_F5: string += "F5"; break;
137 case KeyEvent::VK_KEY_F6: string += "F6"; break;
138 case KeyEvent::VK_KEY_F7: string += "F7"; break;
139 case KeyEvent::VK_KEY_F8: string += "F8"; break;
140 case KeyEvent::VK_KEY_F9: string += "F9"; break;
141 case KeyEvent::VK_KEY_F10: string += "F10"; break;
142 case KeyEvent::VK_KEY_F11: string += "F11"; break;
143 case KeyEvent::VK_KEY_F12: string += "F12"; break;
144 case KeyEvent::VK_KEY_F13: string += "F13"; break;
145 case KeyEvent::VK_KEY_F14: string += "F14"; break;
146 case KeyEvent::VK_KEY_F15: string += "F15"; break;
147 case KeyEvent::VK_KEY_F16: string += "F16"; break;
148 case KeyEvent::VK_KEY_F17: string += "F17"; break;
149 case KeyEvent::VK_KEY_F18: string += "F18"; break;
150 case KeyEvent::VK_KEY_F19: string += "F19"; break;
151 case KeyEvent::VK_KEY_F20: string += "F20"; break;
152 case KeyEvent::VK_KEY_F21: string += "F21"; break;
153 case KeyEvent::VK_KEY_F22: string += "F22"; break;
154 case KeyEvent::VK_KEY_F23: string += "F23"; break;
155 case KeyEvent::VK_KEY_F24: string += "F24"; break;
156 case KeyEvent::LIB_VK_META: string += "META"; break;
157 case KeyEvent::LIB_VK_SHIFT: string += "SHIFT"; break;
158 case KeyEvent::LIB_VK_MENU: string += "ALT"; break;
159 case KeyEvent::LIB_VK_RCONTROL: string += "RCTRL"; break;
160 case KeyEvent::LIB_VK_LCONTROL: string += "LCTRL"; break;
161 case KeyEvent::LIB_VK_SPACE: string += "SPACE"; break;
162 case KeyEvent::LIB_VK_ESCAPE: string += "ESC"; break;
163 case KeyEvent::LIB_VK_DELETE: string += "DEL"; break;
164 case KeyEvent::LIB_VK_RETURN: string += "ENTER"; break;
165 case KeyEvent::LIB_VK_EXECUTE: string += "EXE"; break;
166 case KeyEvent::LIB_VK_BUTTON_A: string += "A"; break;
167 case KeyEvent::LIB_VK_BUTTON_B: string += "B"; break;
168 case KeyEvent::LIB_VK_BUTTON_X: string += "X"; break;
169 case KeyEvent::LIB_VK_BUTTON_Y: string += "Y"; break;
170 case KeyEvent::LIB_VK_BUTTON_L1: string += "L1"; break;
171 case KeyEvent::LIB_VK_BUTTON_R1: string += "R1"; break;
172 case KeyEvent::LIB_VK_BUTTON_SELECT: string += "SELECT"; break;
173 case KeyEvent::LIB_VK_BUTTON_START: string += "START"; break;
174 case KeyEvent::LIB_VK_BUTTON_MODE: string += "MODE"; break;
175 case KeyEvent::LIB_VK_BUTTON_THUMBL: string += "TL"; break;
176 case KeyEvent::LIB_VK_BUTTON_THUMBR: string += "TR"; break;
177 case KeyEvent::LIB_VK_VOLUME_UP: string += "VOL+"; break;
178 case KeyEvent::LIB_VK_VOLUME_DOWN: string += "VOL-"; break;
179 default:
180 string += "("+String(cast<uint04>(value.key_type))+")";
181 break;
182 }
183 } break;
184 default:
185 string += cast<char>(toupper(value.toChar()));
186 break;
187 }
188 translated_string = TranslatedString(string);
189 }
190 \endcode
191 Example code for auomatic conversion to enums:
192 \code
193 template<> void
194 StringStream<CompressionMode>::fromString(const String& string, CompressionMode& value)
195 {
196 switch (string.hashUpper())
197 {
198 case String::hash("DEFAULT"): value = CompressionMode::e_default; break;
199 case String::hash("BEST"): value = CompressionMode::e_best; break;
200 case String::hash("NONE"): value = CompressionMode::e_none; break;
201 }
202 }
203 template<> void
204 StringStream<CompressionMode>::toString(const CompressionMode& value, String& string)
205 {
206 switch (value) {
207 case CompressionMode::e_default: string.addAll("DEFAULT"); break;
208 case CompressionMode::e_best: string.addAll("BEST"); break;
209 case CompressionMode::e_none: string.addAll("NONE"); break;
210 default: lib_assert(false, "unknown value"); string.addAll(String(cast<uint01>(value))); break;
211 }
212 }
213 template<> void
214 StringStream<CompressionMode>::toDisplayString(const CompressionMode& value, TranslatedString& string)
215 {
216 switch (value) {
217 case CompressionMode::e_default_compression: string = _t("Default Compression"); break;
218 case CompressionMode::e_best_compression: string = _t("Best Compression"); break;
219 case CompressionMode::e_best_speed: string = _t("Best Speed"); break;
220 case CompressionMode::e_no_compression: string = _t("No Compression"); break;
221 case CompressionMode::e_string_compression: string = _t("String Compression"); break;
222 case CompressionMode::e_floating_point_compression: string = _t("Number Compression"); break;
223 default: lib_assert(false, "unknown value"); break;
224 }
225 }
226 \endcode
227 **/
228 template<class t_type>
230 {
231 public:
232 /**--------------------------------------------------------------------------------------------------
233 \brief Logic for converting an object to an NDEVR API String allowing it to be used automatically
234 with the String constructor, GenericOptions, Scanners, and various other data structures.
235 **/
236 static void toString(const t_type& value, String& string);
237
238 /**--------------------------------------------------------------------------------------------------
239 \brief Logic for converting an object to an NDEVR API translated, user facing string. This allows
240 the object to be shown in a unique way to a user.
241 If not overwritten, will default to the value returned from toString
242 **/
243 static void toDisplayString(const t_type& value, TranslatedString& string);
244
245 /**--------------------------------------------------------------------------------------------------
246 \brief Logic for converting an object from an NDEVR API String allowing it to be used automatically
247 with getAs<>(), Files, GenericOptions, and various other data structures.
248 **/
249 static void fromString(const String& string, t_type& value);
250
251 /**--------------------------------------------------------------------------------------------------
252 \brief Optionally specified to allow the software to do a check on user or file input to ensure that
253 fromString will return a valid result or to limit user live input.
254 **/
255 static const char* getValidRegex();
256 };
257 template<>
259 {
260 public:
261 static void toString(const String& value, String& string);
262 static void toDisplayString(const String& value, TranslatedString& string);
263 static void fromString(const String& string, String& value);
264 static const char* getValidRegex();
265 };
266 template<uint01 t_dims, class t_type>
267 class StringStream<Vector<t_dims, t_type>>
268 {
269 public:
270 static void toString(const Vector<t_dims, t_type>& value, String& string)
271 {
272 StringStream<t_type>::toString(value[0], string);
273 for (uint01 dim = 1; dim < t_dims; ++dim)
274 {
275 StringStream<char>::toString(',', string);
276 StringStream<t_type>::toString(value[dim], string);
277 }
278 }
279
280 static void fromString(const String& string, Vector<t_dims, t_type>& value)
281 {
282 if constexpr (ObjectInfo<t_type>::Number)
283 {
284 const char* iter = StringSplitter::begin(string);
285 const char* end = StringSplitter::end(string);
286 for (uint01 dim = 0; dim < t_dims; ++dim)
287 {
288 value[dim] = NumberParser::parse<t_type>(iter, &iter);
289 for (; iter < end; iter++)
290 {
291 if (*iter == ',')
292 break;
293 }
294 if (iter == end)
295 {
296 ++dim;
297 for (; dim < t_dims; ++dim)
298 {
299 value[dim] = Constant<t_type>::Invalid;
300 }
301 return;
302 }
303 iter++;//skip over ,
304 }
305 }
306 else
307 {
308 Buffer<String, uint04, ObjectAllocator<false>> parts = StringSplitter::split(string, ',');
309 for (uint01 dim = 0; dim < t_dims; ++dim)
310 {
311 if (parts.size() > dim)
312 {
313 t_type val = value[dim];
314 StringStream<t_type>::fromString(parts[dim], val);
315 value[dim] = val;
316 }
317 else
318 value[dim] = Constant<t_type>::Invalid;
319 }
320 }
321 }
322 static void toDisplayString(const Vector<t_dims, t_type>& value, TranslatedString& string) { return toString(value, string); }
323 static const char* getValidRegex()
324 {
325 return ".*";
326 };
327 };
328
329
330 template<uint01 t_dims, class t_type>
331 class StringStream<Bounds<t_dims, t_type>>
332 {
333 public:
334 static void toString(const Bounds<t_dims, t_type>& value, String& string)
335 {
336 StringStream<Vector<t_dims, t_type>>::toString(value[MIN], string);
337 StringStream<char>::toString('^', string);
338 StringStream<Vector<t_dims, t_type>>::toString(value[MAX], string);
339 }
340
341 static void fromString(const String& string, Bounds<t_dims, t_type>& value)
342 {
343 Buffer<String, uint04, ObjectAllocator<false>> parts = StringSplitter::split(string, '^');
344 if (parts.size() < 2)
345 {
346 value = Constant<Bounds<t_dims, t_type>>::Invalid;
347 }
348 else
349 {
350 StringStream<Vector<t_dims, t_type>>::fromString(parts[0], value[MIN]);
351 StringStream<Vector<t_dims, t_type>>::fromString(parts[1], value[MAX]);
352 }
353
354 }
355 static void toDisplayString(const Bounds<t_dims, t_type>& value, String& string) { return toString(value, string); }
356 static const char* getValidRegex()
357 {
358 return ".*";
359 };
360 };
361
362 template<uint01 t_dims, class t_type, class t_vector_type>
363 class StringStream<Vertex<t_dims, t_type, t_vector_type>>
364 {
365 public:
366 static void toString(const Vertex<t_dims, t_type, t_vector_type>& value, String& string)
367 {
369 }
370
371 static void fromString(const String& string, Vertex<t_dims, t_type, t_vector_type>& value)
372 {
374 }
375 static void toDisplayString(const Vertex<t_dims, t_type, t_vector_type>& value, TranslatedString& string) { return toString(value, string); }
376 static const char* getValidRegex()
377 {
378 return ".*";
379 };
380 };
381 template<uint01 t_dims, class t_type, class t_vector_type>
382 class StringStream<Ray<t_dims, t_type, t_vector_type>>
383 {
384 public:
385 static void toString(const Ray<t_dims, t_type, t_vector_type>& value, String& string)
386 {
388 }
389
390 static void fromString(const String& string, Ray<t_dims, t_type, t_vector_type>& value)
391 {
393 }
394 static void toDisplayString(const Ray<t_dims, t_type, t_vector_type>& value, TranslatedString& string) { return toString(value, string); }
395 static const char* getValidRegex()
396 {
397 return ".*";
398 };
399 };
400 template<class t_type, class t_index_type, class t_memory_allocater, class t_memory_manager>
401 class StringStream<Buffer<t_type, t_index_type, t_memory_allocater, t_memory_manager>>
402 {
403 public:
404 static void toString(const Buffer<t_type, t_index_type, t_memory_allocater, t_memory_manager>& value, String& string)
405 {
406 for (uint04 i = 0; i < value.size(); i++)
407 {
408 StringStream<t_type>::toString(value[i], string);
409 }
410 }
411
412 static void fromString(const String& string, Buffer<t_type, t_index_type, t_memory_allocater, t_memory_manager>& value)
413 {
414 Buffer<String, uint04, ObjectAllocator<false>> strings = StringSplitter::split(string, ',');
415 value.setSize(strings.size());
416 for (uint04 i = 0; i < value.size(); i++)
417 {
418 StringStream<t_type>::fromString(strings[i], value[i]);
419 }
420 }
421 static void toDisplayString(const Buffer<t_type, t_index_type, t_memory_allocater, t_memory_manager>& value, TranslatedString& string) { return toString(value, string); }
422 static const char* getValidRegex()
423 {
424 return ".*";
425 };
426 };
427
428 /*template<typename t_type, typename std::enable_if<std::is_enum<t_type>::value>::type>
429 class StringStream<t_type>
430 {
431 public:
432 static void toString(const t_type& value, String& string)
433 {
434 StringStream<sint04>::toString(value, string);
435 }
436 static void fromString(const String& string, t_type& value)
437 {
438 StringStream<sint04>::fromString(string, value);
439 }
440
441 static const char* getValidRegex()
442 {
443 return StringStream<sint04>::getValidRegex();
444 };
445 };*/
446 template<class t_type, uint01 t_row_dims, uint01 t_col_dims>
447 class StringStream<Matrix<t_type, t_row_dims, t_col_dims>>
448 {
449 public:
450 static void toString(const Matrix<t_type, t_row_dims, t_col_dims>& value, String& string)
451 {
452 for (uint01 col = 0; col < t_col_dims; ++col)
453 {
454 StringStream<t_type>::toString(value[col][0], string);
455 for (uint01 row = 1; row < t_row_dims; ++row)
456 {
457 StringStream<char>::toString(',', string);
458 StringStream<t_type>::toString(value[col][row], string);
459 }
460 StringStream<char>::toString(';', string);
461 }
462 }
463
464 static void fromString(const String& string, Matrix<t_type, t_row_dims, t_col_dims>& value)
465 {
466 Buffer<String, uint04, ObjectAllocator<false>> columns = StringSplitter::split(string, ';');
467 for (uint01 col = 0; col < t_col_dims; ++col)
468 {
469 if (col < columns.size())
470 {
471 Buffer<String, uint04, ObjectAllocator<false>> rows = StringSplitter::split(columns[col], ',');
472 for (uint01 row = 0; row < t_row_dims; ++row)
473 {
474 if (row < rows.size())
475 StringStream<t_type>::fromString(rows[row], value[col][row]);
476 else
477 value[col][row] = Constant<t_type>::Invalid;
478 }
479 }
480 else
481 {
482 for (uint01 row = 0; row < t_row_dims; ++row)
483 {
484 value[col][row] = Constant<t_type>::Invalid;
485 }
486 }
487 }
488 }
489 static void toDisplayString(const Matrix<t_type, t_row_dims, t_col_dims>& value, TranslatedString& string) { return toString(value, string); }
490 static const char* getValidRegex()
491 {
492 return ".*";
493 };
494 };
495 template class NDEVR_BASE_API StringStream<bool>;
496 template class NDEVR_BASE_API StringStream<char>;
497 template class NDEVR_BASE_API StringStream<wchar>;
498 template class NDEVR_BASE_API StringStream<sint01>;
499 template class NDEVR_BASE_API StringStream<sint02>;
500 template class NDEVR_BASE_API StringStream<sint04>;
501 template class NDEVR_BASE_API StringStream<sint08>;
502 template class NDEVR_BASE_API StringStream<uint01>;
503 template class NDEVR_BASE_API StringStream<uint02>;
504 template class NDEVR_BASE_API StringStream<uint04>;
505 template class NDEVR_BASE_API StringStream<uint08>;
506 template class NDEVR_BASE_API StringStream<fltp04>;
507 template class NDEVR_BASE_API StringStream<fltp08>;
508 class BitReference;
509 template class NDEVR_BASE_API StringStream<BitReference>;
511 template class NDEVR_BASE_API StringStream<InterpolationValues>;
512
513 template class NDEVR_BASE_API StringStream<char const*>;
514 template class NDEVR_BASE_API StringStream<char*>;
515 template class NDEVR_BASE_API StringStream<wchar const*>;
516 template class NDEVR_BASE_API StringStream<wchar*>;
517 class BitFlag;
518 template class NDEVR_BASE_API StringStream<BitFlag>;
519 struct Font;
520 template class NDEVR_BASE_API StringStream<Font>;
521 class RGBColor;
522 template class NDEVR_BASE_API StringStream<RGBColor>;
523 class ACIColor;
524 template class NDEVR_BASE_API StringStream<ACIColor>;
525 class XYZColor;
526 template class NDEVR_BASE_API StringStream<XYZColor>;
527 class LABColor;
528 template class NDEVR_BASE_API StringStream<LABColor>;
529 class HSLColor;
530 template class NDEVR_BASE_API StringStream<HSLColor>;
531 class HSBColor;
532 template class NDEVR_BASE_API StringStream<HSBColor>;
533 class Time;
534 template class NDEVR_BASE_API StringStream<Time>;
535 class TimeSpan;
536 template class NDEVR_BASE_API StringStream<TimeSpan>;
537 class UUID;
538 template class NDEVR_BASE_API StringStream<UUID>;
539 template<class t_type>
540 class Angle;
543 class File;
544 template class NDEVR_BASE_API StringStream<File>;
545 class TranslatedString;
547
550}
#define NDEVR_BASE_API
Definition DLLInfo.h:57
The primary angle storage class for this API. Stores an angle in an optimized format.
Definition StringStream.h:540
The equivelent of std::vector but with a bit more control. The basic array unit of the library.
Definition Buffer.hpp:56
Logic for reading or writing to a file as well as navigating filesystems.
Definition File.h:48
static t_type parse(const char *in, const char **out=nullptr, t_type Invalid_Value=Constant< t_type >::Invalid, bool check_overflow=true)
Definition NumberParser.hpp:86
The core String class for the NDEVR API.
Definition String.h:69
Logic for splitting a string into two.
Definition StringStream.h:52
static const char * begin(const String &s)
static Buffer< String, uint04, ObjectAllocator< false > > split(const String &s, char split)
static const char * end(const String &s)
Logic for reading or writing to a string or a user friendly, TranslatedString.
Definition StringStream.h:230
static void toString(const t_type &value, String &string)
Logic for converting an object to an NDEVR API String allowing it to be used automatically with the S...
static void fromString(const String &string, t_type &value)
Logic for converting an object from an NDEVR API String allowing it to be used automatically with get...
static const char * getValidRegex()
Optionally specified to allow the software to do a check on user or file input to ensure that fromStr...
static void toDisplayString(const t_type &value, TranslatedString &string)
Logic for converting an object to an NDEVR API translated, user facing string. This allows the object...
Any text displayed to the user should be defined as a TranslatedString which allows the program to lo...
Definition TranslatedString.h:13
Stores information about a type, relevant for certain templated functions. To get information about a...
Definition TypeInfo.h:43
Logic for creating a regex for a given type of data.
Definition StringStream.h:62
static const char * ValidRegex(const TypeInfo &info)
Definition ACIColor.h:37
@ MIN
Definition BaseValues.hpp:196
@ MAX
Definition BaseValues.hpp:197
InterpolationValues
Values that represent interpolation functions. Useful in large or complicated geological or time base...
Definition BaseValues.hpp:221
uint8_t uint01
-Defines an alias representing a 1 byte, unsigned integer -Can represent exact integer values 0 throu...
Definition BaseValues.hpp:80
uint32_t uint04
-Defines an alias representing a 4 byte, unsigned integer -Can represent exact integer values 0 throu...
Definition BaseValues.hpp:96
static const t_type Invalid
Definition BaseValues.hpp:234