Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
Support.h
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#ifndef _Stroika_Frameworks_Led_Support_h_
5#define _Stroika_Frameworks_Led_Support_h_ 1
6
7#include "Stroika/Frameworks/StroikaPreComp.h"
8
9#include <climits>
10#include <cstddef>
11#include <cstdint>
12#include <cstring>
13#include <functional>
14#include <new>
15#include <string>
16#include <vector>
17
18#if qStroika_Foundation_Common_Platform_Windows
19#include <Windows.h> //
20
21#include <oaidl.h> // for SAFEARRAY
22#include <tchar.h>
23#elif qStroika_FeatureSupported_XWindows
24#include <X11/X.h>
25#include <X11/Xatom.h>
26#endif
27
28#include "Stroika/Foundation/Characters/SDKString.h"
29#include "Stroika/Foundation/Common/Common.h"
33#include "Stroika/Foundation/Execution/Throw.h"
34#include "Stroika/Foundation/Memory/Common.h"
36#include "Stroika/Frameworks/Led/Config.h"
37
38#if qStroika_Foundation_Common_Platform_Windows
39#include "Stroika/Foundation/Execution/Platform/Windows/HRESULTErrorException.h"
40#endif
41
42/*
43@MODULE: LedSupport
44@DESCRIPTION:
45 <p>Support defines, and utility functions that should usually be provided
46 by some other class library (e.g. Stroika, TCL, MFC, OWL, etc. These
47 defines should just thunk down to the appropriate class library defines -
48 where possible.</p>
49 */
50namespace Stroika {
51 using namespace std;
52 using std::byte;
53
54 using namespace Stroika::Foundation;
55}
56
57namespace Stroika::Frameworks::Led {
58
60
61 constexpr size_t kBadIndex = size_t (-1);
62
63#if qStroika_Foundation_Common_Platform_Windows
65#endif
66
67 /*
68 @CLASS: Led_tChar
69 @todo LOSE THIS TYPE!!!! - use Stroika::FoundationL::Character::Charactrer
70
71 STILL need define for chararcter encoding version of GDI API (qTargetPlatformSDKUseswchar_t)
72
73 For now - use wchar_t - since thats what I did for a long time.
74
75 But Stroika Character better.
76
77 ANd in TextStore - do same tricks I do with String - have one REP where size is one-byte (ISOLATIN) - and one case where size is char16_t (no surrogagtes)
78 and one case for char32_t. THen copyOut magic does right mapping automatically (or have Peek API like I do for String).
79
80 REally - TONS of APIs that use const Led_tChar* should be replaced with span<const Character>..
81
82
83 #if 0
84 @DESCRIPTION: <p>There are lots of different ways of encoding character sets. And it is
85 a goal for Led to be able to support them all. The three major ways are wide characters,
86 single-byte characters, and multibyte character strings.</p>
87 <p><code>Led_tChar</code> is a basic type used throughout Led. In the
88 case of single byte character systems it is a <code>char</code>, and this also corresponds
89 to a character. In mutlibyte character systems, it is also of type <code>char</code>,
90 but then it does NOT correspond to a character. Rather some consecutive sequence
91 of <code>Led_tChar</code>s specify a character. And for wide character sets (e.g UNICODE),
92 <code>Led_tChar</code> is of type <code>wchar_t</code>, and - like with single byte
93 character sets - does contain a full character.</p>
94
95 <p>Now simply supporting one of these would be easy. Support all three within the
96 same code base requires a small amount of discipline. It requires that we never assume that
97 <code> sizeof (char) == sizeof (Led_tChar)</code> - because that supposed equality <b>is not true</b>.
98 And it requires that we not assume that every possible <code>Led_tChar</code> pointer
99 refers to a valid character beginning. Instead, we must use utility routines
100 <code><a href=#Led_MutlibyteCharRoutines>Led_NextChar</a></code> and
101 <code><a href=#Led_MutlibyteCharRoutines>Led_PreviousChar</a></code> to navigate through
102 <code>Led_tChar*</code> strings.</p>
103
104 <p>All of Led's APIs which refer to characters or bytes or any such thing <em>really</em>
105 refer to <code>Led_tChar</code>s (actually, typically <code>Led_tChar*</code>).
106 All of Led's APIs gaurantee (unless otherwise noted) that they will never split a character
107 (return a character offset which points in the middle of a multibyte character).
108 And all of Led's APIs similarly <em>require</em> that all offsets and strings passed to
109 it consist of valid character boundaries.
110 You can always use (and Led does many asserts internally)
111 <code>ValidateTextForCharsetConformance()</code> to check / validate a string to make
112 sure it is valid with respect to the character set you are using (for example doesn't end
113 spliting a multibyte character).</p>
114 #endif
115 */
116#if defined(__cplusplus)
117 using Led_tChar = wchar_t;
118#endif
119
120/*
121 @CLASS: LED_TCHAR_OF
122 @DESCRIPTION: <p>Like the Win32SDK macro _T(). Except is based on the Led type @'Led_tChar', and the Led
123 macros @'qSingleByteCharacters', @'qMultiByteCharacters', and @'qWideCharacters'.</p>
124 */
125#define LED_TCHAR_OF__(X) L##X
126#define LED_TCHAR_OF(X) LED_TCHAR_OF__ (X)
127
128 constexpr wchar_t kNonBreakingSpace = 0x00a0;
129 constexpr wchar_t kZeroWidthSpace = 0x200b;
130 constexpr wchar_t kPoundSign = 0x00a3;
131 constexpr wchar_t kCentSign = 0x00a2;
132 constexpr wchar_t kYenSign = 0x00a5;
133
134 /*
135 @CLASS: Led_tString
136 @DESCRIPTION: <p>This expands to either the ANSI C++ string class library class <code>string</code>
137 or <code>wstring</code> - depending on whether we are using UNICODE or not. It is a <code>basic_string</code>
138 templated on @'Led_tChar'.</p>
139 */
140 using Led_tString = basic_string<Led_tChar>;
141
142 /*
143 @METHOD: Led_tStrlen
144 @DESCRIPTION: <p>Expands to any of the ANSI C++ functions, std::strlen ()/wcslen/_mbstrlen(not ansiC++), depending on
145 macros @'qSingleByteCharacters', @'qMultiByteCharacters', and @'qWideCharacters'.</p>
146 */
147 size_t Led_tStrlen (const Led_tChar* s);
148
149 /*
150 @METHOD Led_tStrCmp
151 @DESCRIPTION: <p>Expands to any of the ANSI C++ functions, std::strcmp/etc, depending on
152 macros @'qSingleByteCharacters', @'qMultiByteCharacters', and @'qWideCharacters'.</p>
153 */
154 int Led_tStrCmp (const Led_tChar* l, const Led_tChar* r);
155
156 /*
157 @METHOD: Led_tStrnCmp
158 @DESCRIPTION: <p>Expands to any of the ANSI C++ functions, std::strncmp/etc, depending on
159 macros @'qSingleByteCharacters', @'qMultiByteCharacters', and @'qWideCharacters'.</p>
160 */
161 int Led_tStrnCmp (const Led_tChar* l, const Led_tChar* r, size_t n);
162
163 /*
164 @METHOD: Led_tStrniCmp
165 @DESCRIPTION: <p>Expands to any of the ANSI C++ functions, std::strnicmp/etc, depending on
166 macros @'qSingleByteCharacters', @'qMultiByteCharacters', and @'qWideCharacters'. See also @'Led_tStriCmp'.</p>
167 */
168 int Led_tStrniCmp (const Led_tChar* l, const Led_tChar* r, size_t n);
169
170 /*
171 @METHOD: Led_tStriCmp
172 @DESCRIPTION: <p>Expands to any of the ANSI C++ functions, std::stricmp/etc, depending on
173 macros @'qSingleByteCharacters', @'qMultiByteCharacters', and @'qWideCharacters'. See also @'Led_tStrniCmp'.</p>
174 */
175 int Led_tStriCmp (const Led_tChar* l, const Led_tChar* r);
176
177 /*
178 @METHOD: Led_tStrChr
179 @DESCRIPTION: <p>Expands to any of the ANSI C++ functions, std::strchr/etc, depending on
180 macros @'qSingleByteCharacters', @'qMultiByteCharacters', and @'qWideCharacters'.</p>
181 */
182 const Led_tChar* Led_tStrChr (const Led_tChar* s, Led_tChar c);
183
184/*
185 @CLASS: Led_SDK_TCHAROF
186 @DESCRIPTION: <p>Like the Win32SDK macro _T(). See @'SDKString'.</p>
187 */
188#if qTargetPlatformSDKUseswchar_t
189#define Led_SDK_TCHAROF(X) LED_TCHAR_OF__ (X)
190#else
191#define Led_SDK_TCHAROF(X) X
192#endif
193
194 /*
195 @METHOD: Led_tString2SDKString
196 @DESCRIPTION:
197 */
198 SDKString Led_tString2SDKString (const Led_tString& s);
199
200 /*
201 @METHOD: Led_WideString2tString
202 @DESCRIPTION:
203 */
204 Led_tString Led_WideString2tString (const wstring& s);
205
206 /*
207 @METHOD: Led_SDKString2tString
208 @DESCRIPTION:
209 */
210 Led_tString Led_SDKString2tString (const SDKString& s);
211
212 /*
213 @METHOD: Led_ANSIString2tString
214 @DESCRIPTION:
215 */
216 Led_tString Led_ANSIString2tString (const string& s);
217
218 /*
219 @METHOD: Led_tString2ANSIString
220 @DESCRIPTION:
221 */
222 string Led_tString2ANSIString (const Led_tString& s);
223
224 /*
225 @METHOD: Led_tString2WideString
226 @DESCRIPTION:
227 */
228 wstring Led_tString2WideString (const Led_tString& s);
229
230 short Led_ByteSwapFromMac (short src);
231 unsigned short Led_ByteSwapFromMac (unsigned short src);
232
233 short Led_ByteSwapFromWindows (short src);
234 unsigned short Led_ByteSwapFromWindows (unsigned short src);
235 long Led_ByteSwapFromWindows (long src);
236 unsigned long Led_ByteSwapFromWindows (unsigned long src);
237
238 void UInt16ToBuf (uint16_t u, uint16_t* realBuf);
239 uint16_t BufToUInt16 (const uint16_t* realBuf);
240 void UInt32ToBuf (uint32_t ul, uint32_t* realBuf);
241 uint32_t BufToUInt32 (const uint32_t* buf);
242
243 /*
244 * Store as UInt32, but throw if won't fit
245 */
246 void SizeTToBuf (size_t ul, uint32_t* realBuf);
247 size_t BufToSizeT (const uint32_t* buf);
248
249 size_t Led_SkrunchOutSpecialChars (Led_tChar* text, size_t textLen, Led_tChar charToRemove);
250
251 /*
252 @METHOD: PUSH_BACK
253 @DESCRIPTION: <p></p>
254 */
255 template <class VECTOR>
256 inline void PUSH_BACK (VECTOR& v, const typename VECTOR::value_type& e)
257 {
258 size_t vSize = v.size ();
259 size_t vCap = v.capacity ();
260 Assert (vSize <= vCap);
261 if (vSize == vCap) {
262 size_t newCap = vSize * 2;
263 newCap = max (newCap, size_t (4));
264 v.reserve (newCap); // grow by factor of 2 to assure logarithmic # of copies rather than quadradic
265 }
266 v.push_back (e);
267 }
268
269 /*
270 @CLASS: DiscontiguousRunElement<DATA>
271 @DESCRIPTION: <p>We frequently need to keep track of runs of data. Sometimes - those elements are discontiguous.
272 This template is merely used to give us a uniform naming convention for how we deal with those runs.</p>
273 <p>These elements are meant to be used with @'DiscontiguousRun<DATA>'.</p>
274 */
275 template <typename DATA>
276 struct DiscontiguousRunElement {
277 DiscontiguousRunElement (size_t offset, size_t length)
278 : fOffsetFromPrev{offset}
279 , fElementLength{length}
280 {
281 }
282 DiscontiguousRunElement (size_t offset, size_t length, const DATA& data)
283 : fOffsetFromPrev{offset}
284 , fElementLength{length}
285 , fData{data}
286 {
287 }
288
289 size_t fOffsetFromPrev;
290 size_t fElementLength;
291 DATA fData{};
292 };
293 template <>
294 struct DiscontiguousRunElement<void> {
295 DiscontiguousRunElement (size_t offset, size_t length)
296 : fOffsetFromPrev{offset}
297 , fElementLength{length}
298 {
299 }
300 size_t fOffsetFromPrev;
301 size_t fElementLength;
302 };
303
304 /*
305 @CLASS: DiscontiguousRun<DATA>
306 @DESCRIPTION: <p>An ordered list of @'DiscontiguousRunElement<DATA>'. The ordering is very important. The 'fOffsetFromPrev'
307 is the offset in marker-positions the data is intended to be from the end of the previous element. For the first
308 element - this if the offset from the 'beginning'.</p>
309 <p>NB: I would PREFER to have declared this as a typedef - so I would get the vector<> ctors for free. But
310 I couldn't figure out how to declare it in a way that made MSVC60 happy. So I settled for this.</p>
311 */
312 template <typename DATA>
313 struct DiscontiguousRun : vector<DiscontiguousRunElement<DATA>> {};
314
315 /*
316 * These routines can be used either with single byte, multibyte, or wide
317 * characters. They are intended to insulate most of the code from having
318 * to worry about this.
319 */
320 /*
321 @METHOD: Led_NextChar
322 @DESCRIPTION: <p>See @'Led_tChar'</p>
323
324 @todo DEPRECATE - NO POINT IN THIS API ANY LONGER -- LGP 2024-02-12
325 */
326 Led_tChar* Led_NextChar (Led_tChar* fromHere);
327 const Led_tChar* Led_NextChar (const Led_tChar* fromHere);
328
329 /*
330 @METHOD: Led_PreviousChar
331 @DESCRIPTION: <p>See @'Led_tChar'</p>
332
333 @todo DEPRECATE - NO POINT IN THIS API ANY LONGER -- LGP 2024-02-12
334 */
335 Led_tChar* Led_PreviousChar (Led_tChar* startOfString, Led_tChar* fromHere);
336 const Led_tChar* Led_PreviousChar (const Led_tChar* startOfString, const Led_tChar* fromHere);
337
338 /*
339 @METHOD: ValidateTextForCharsetConformance
340 @DESCRIPTION: <p>See @'Led_tChar'</p>
341
342 @todo DEPRECATE - NO POINT IN THIS API ANY LONGER -- LGP 2024-02-12
343 */
344 bool ValidateTextForCharsetConformance (const Led_tChar* text, size_t length); // just return true or false - no other diagnostics
345
346 unsigned Led_DigitCharToNumber (char digitChar); // require input is valid decimal digit
347 char Led_NumberToDigitChar (unsigned digitValue); // require input is valid decimal digit value
348
349 bool Led_CasedCharsEqual (char lhs, char rhs, bool ignoreCase = true);
350 bool Led_CasedStringsEqual (const string& lhs, const string& rhs, bool ignoreCase = true);
351 bool Led_CasedStringsEqual (const string_view& lhs, const string_view& rhs, bool ignoreCase = true);
352 bool Led_CasedStringsEqual (const string_view& lhs, const string& rhs, bool ignoreCase = true);
353 bool Led_CasedStringsEqual (const string& lhs, const string_view& rhs, bool ignoreCase = true);
354 bool Led_CasedStringsEqual (const char* lhs, const string& rhs, bool ignoreCase = true);
355 bool Led_CasedStringsEqual (const string& lhs, const char* rhs, bool ignoreCase = true);
356 bool Led_CasedStringsEqual (const char* lhs, const string_view& rhs, bool ignoreCase = true);
357 bool Led_CasedStringsEqual (const string_view& lhs, const char* rhs, bool ignoreCase = true);
358 bool Led_CasedStringsEqual (const char* lhs, const char* rhs, bool ignoreCase = true);
359
360/*
361 * Clipboard access support.
362 *
363 * Note - when using this on the PC - be sure clipboard opened/closed
364 * surrounding access to this object - as is currently done in Led_MFC.
365 *
366 */
367#ifndef qStroika_Frameworks_Led_SupportClipboard
368#define qStroika_Frameworks_Led_SupportClipboard (qStroika_Foundation_Common_Platform_Windows or qStroika_FeatureSupported_XWindows)
369#endif
370
371#if qStroika_Foundation_Common_Platform_Windows
372 using Led_ClipFormat = CLIPFORMAT;
373#elif qStroika_FeatureSupported_XWindows
374 using Led_ClipFormat = long;
375#else
376 // used in a lot of places to exchange info, even if not to a real clipboad, so keep type defined for now ... --LGP 2024-02-11
377 enum Led_ClipFormat : unsigned short {
378 };
379#endif
380#if qStroika_Foundation_Common_Platform_Windows
381 const Led_ClipFormat kTEXTClipFormat = CF_UNICODETEXT;
382 // const Led_ClipFormat kPICTClipFormat = CF_METAFILEPICT;
383 const Led_ClipFormat kPICTClipFormat = CF_DIB;
384 const Led_ClipFormat kFILEClipFormat = CF_HDROP;
385#elif qStroika_FeatureSupported_XWindows
386 const Led_ClipFormat kTEXTClipFormat = XA_STRING;
387 const Led_ClipFormat kFILEClipFormat = 1; // X-TMP-HACK-LGP991213 - not sure what this should be???
388#else
389 const Led_ClipFormat kTEXTClipFormat = (Led_ClipFormat)1;
390 const Led_ClipFormat kFILEClipFormat = (Led_ClipFormat)2;
391#endif
392 const Led_ClipFormat kBadClipFormat = (Led_ClipFormat)(0);
393
394#if qStroika_Frameworks_Led_SupportClipboard
395 class Led_ClipboardObjectAcquire {
396 public:
397 Led_ClipboardObjectAcquire (Led_ClipFormat clipType);
398 ~Led_ClipboardObjectAcquire ();
399
400 static bool FormatAvailable_TEXT ();
401 static bool FormatAvailable (Led_ClipFormat clipType);
402
403 nonvirtual bool GoodClip () const; // avoid exceptions usage for now - and just use flag
404 nonvirtual void* GetData () const;
405 nonvirtual size_t GetDataLength () const;
406
407 private:
408#if qStroika_Foundation_Common_Platform_Windows
409 HANDLE fOSClipHandle;
410#endif
411 void* fLockedData;
412 };
413#endif
414
415 void Led_BeepNotify ();
416 Foundation::Time::DurationSeconds Led_GetDoubleClickTime (); // time-interval which defines how quick we consider two consecutive clicks a dbl-click
417
418#if qStroika_FeatureSupported_XWindows
419 extern void (*gBeepNotifyCallBackProc) ();
420 unsigned long LedTickCount2XTime (float ledTickCount);
421 void SyncronizeLedXTickCount (unsigned long xTickCount);
422#endif
423
424#if qStroika_Foundation_Common_Platform_Windows
425 class VariantArrayPacker {
426 public:
427 VariantArrayPacker (VARIANT* v, VARTYPE vt, size_t nElts);
428 ~VariantArrayPacker ();
429
430 public:
431 nonvirtual void* PokeAtData () const;
432
433 private:
434 VARIANT* fSafeArrayVariant{nullptr};
435 void* fPtr{nullptr};
436 };
437
438 class VariantArrayUnpacker {
439 public:
440 VariantArrayUnpacker (const VARIANT& v);
441 ~VariantArrayUnpacker ();
442
443 public:
444 nonvirtual const void* PeekAtData () const;
445 nonvirtual VARTYPE GetArrayElementType () const;
446 nonvirtual size_t GetLength () const;
447
448 private:
449 SAFEARRAY* fSafeArray;
450 const void* fPtr;
451 };
452#endif
453
454#if qStroika_Foundation_Common_Platform_Windows
455 VARIANT CreateSafeArrayOfBSTR (const wchar_t* const* strsStart, const wchar_t* const* strsEnd);
456 VARIANT CreateSafeArrayOfBSTR (const vector<const wchar_t*>& v);
457 VARIANT CreateSafeArrayOfBSTR (const vector<wstring>& v);
458
459 vector<wstring> UnpackVectorOfStringsFromVariantArray (const VARIANT& v);
460#endif
461
462#if qStroika_Foundation_Common_Platform_Windows
463 void DumpSupportedInterfaces (IUnknown* obj, const char* objectName = nullptr, const char* levelPrefix = nullptr);
464 void DumpObjectsInIterator (IEnumUnknown* iter, const char* iteratorName = nullptr, const char* levelPrefix = nullptr);
465#endif
466
467 /*
468 @CLASS: Led_URLD
469 @DESCRIPTION: <p><code>Led_URLD</code> is an abstraction of the Netscape Web Browser URL object.
470 At least thats where the name comes from. And some of its more quirky attributes.
471 This object has two attributes, a URL and a title.
472 It has accessors to convert it into and from the Netscape URLD object format (URLD on mac
473 and "Netscape Bookmark" on windows; same thing).
474 It also can easily be used for dealing with URLs with ActiveX/Microsoft URL representations.</p>
475 <p>See also, @'Led_URLManager'</p>
476 */
477 struct Led_URLD {
478 Led_URLD (const char* url, const char* title);
479 Led_URLD (const void* urlData, size_t nBytes);
480
481 nonvirtual size_t GetURLDLength () const; // return byte count of URLD itself (includes NUL-byte at end)
482 nonvirtual size_t GetURLLength () const; // return byte count of URL itself
483 nonvirtual size_t GetTitleLength () const; // return byte count of title
484
485 nonvirtual char* PeekAtURLD () const;
486 nonvirtual char* PeekAtURL () const; // NB: doesn't return NUL-term string! - check GetURLLength
487 nonvirtual char* PeekAtTitle () const; // NB: doesn't return NUL-term string! - check GetTitleLength
488
489 nonvirtual string GetTitle () const;
490 nonvirtual string GetURL () const;
491
492 vector<char> fData;
493 };
494
495 /*
496 @CLASS: Led_URLManager
497 @DESCRIPTION: <p><code>Led_URLManager</code> is a utility class to deal with opening URLs.
498 Depending on the OS you are running Led with, it can be configured to use
499 <em>DDE</em>, <em>ActiveX</em>, <em>ShellExec</em>, <em>AppleEvents</em>, or
500 <em>Internet Config (IC)</em>.
501 By default, it uses all that make sense for the given operating system in some reasonable
502 order (prefering more robust approaches, and those that work more frequently and those that
503 report better errors).</p>
504 <p>This class also provides a utility - <code>FileSpecToURL</code> - to make a URL object
505 from a full path name.</p>
506 <p>See also, @'Led_URLD'</p>
507 */
508 class Led_URLManager {
509 public:
510 Led_URLManager () = default;
511 virtual ~Led_URLManager () = default;
512
513 public:
514 static Led_URLManager& Get (); // by default builds one, but you can specify your
515 // own. NB: deletes old value, so if you specify
516 // your own, be sure to allocate it with new so it
517 // can be deleted...
518 static void Set (Led_URLManager* newURLMgr);
519
520 public:
521 virtual void Open (const string& url); // throws on detected errors
522 virtual string FileSpecToURL (const filesystem::path& p);
523
524 protected:
525#if qUseActiveXToOpenURLs
526 nonvirtual void Open_ActiveX (const string& url);
527#endif
528#if qUseSpyglassDDESDIToOpenURLs
529 nonvirtual void Open_SpyglassDDE (const string& url);
530#endif
531
532#if qUseSpyglassDDESDIToOpenURLs
533 public:
534 static void InitDDEHandler (); // to be able to open URLs with DDE this must be called, but
535 // it takes over all DDE processing, disabling your app from doing
536 // any other DDE.
537
538 // Use this for more low level extensions of the DDE support...
539 static DWORD sDDEMLInstance; // The DDEML instance identifier.
540 static HDDEDATA CALLBACK SimpleDdeCallBack (UINT /*type*/, UINT /*fmt*/, HCONV /*hconv*/, HSZ /*hsz1*/, HSZ /*hsz2*/,
541 HDDEDATA /*hData*/, DWORD /*dwData1*/, DWORD /*dwData2*/);
542 static const char* SkipToNextArgument (const char* pFormat);
543 static HSZ ClientArguments (const char* pFormat, ...);
544 static char* ExtractArgument (HSZ hszArgs, int iArg);
545 static void ServerReturned (HDDEDATA hArgs, const char* pFormat, ...);
546#endif
547 };
548
549 string MakeSophistsAppNameVersionURL (const string& relURL, const string& appName, const string& extraArgs = string{});
550
551}
552
553/*
554 ********************************************************************************
555 ***************************** Implementation Details ***************************
556 ********************************************************************************
557 */
558#include "Support.inl"
559
560#endif /*_Stroika_Frameworks_Led_Support_h_*/
chrono::duration< double > DurationSeconds
chrono::duration<double> - a time span (length of time) measured in seconds, but high precision.
Definition Realtime.h:57
basic_string< SDKChar > SDKString
Definition SDKString.h:38
STL namespace.