ALib C++ Library
Library Version: 2412 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
alib.hpp
Go to the documentation of this file.
1//==================================================================================================
2/// \file
3/// This header file is part of the \aliblong.
4///
5/// \emoji :copyright: 2013-2024 A-Worx GmbH, Germany.
6/// Published under \ref mainpage_license "Boost Software License".
7///
8/// This header does not belong to a module of \alib, but is
9/// included in any \alibdist.
10/// Its purposes are:
11/// - To identify given \ref GrpALibPreproSymbols related to module selection and enable
12/// corresponding symbols (that may be not given) of dependent modules.
13/// - Provide functions \alib{Bootstrap} and \alib{Shutdown} which select the right bootstrapping
14/// and shutdown methods, depending on the \alibdist_nl.
15///
16/// \note
17/// This header is not shown in inclusion graphs of this documentation, as it is always
18/// included directly or indirectly.
19//==================================================================================================
20#ifndef HPP_ALIB
21#define HPP_ALIB 1
22#pragma once
23
24#define ALIB_VERSION 2412
25#define ALIB_REVISION 0
26
27#ifndef DOXYGEN
28# define DOXYGEN 0
29#endif
30
31#if !DOXYGEN
32
33// #################################################################################################
34// No module selection symbol given but threads? -> choose ALL
35// #################################################################################################
36#if !defined( ALIB_ALOX ) \
37 && !defined( ALIB_BITBUFFER ) \
38 && !defined( ALIB_BOXING ) \
39 && !defined( ALIB_CHARACTERS ) \
40 && !defined( ALIB_CLI ) \
41 && !defined( ALIB_CONFIGURATION) \
42 && !defined( ALIB_CONTAINERS ) \
43 && !defined( ALIB_ENUMS ) \
44 && !defined( ALIB_EXPRESSIONS ) \
45 && !defined( ALIB_FILES ) \
46 && !defined( ALIB_MONOMEM ) \
47 && !defined( ALIB_SINGLETONS ) \
48 && !defined( ALIB_STRINGS ) \
49 && !defined( ALIB_CAMP ) \
50 && !defined( ALIB_TIME ) \
51 && !defined( ALIB_THREADMODEL ) \
52 && !defined( ALIB_THREADS )
53# define ALIB_ALOX 1
54# define ALIB_EXPRESSIONS 1
55# define ALIB_CLI 1
56# define ALIB_FILES 1
57# define ALIB_THREADMODEL 1
58# define ALIB_BITBUFFER 1
59#endif
60
61#if !defined(ALIB_ALOX )
62# define ALIB_ALOX 0
63#endif
64#if !defined(ALIB_BITBUFFER )
65# define ALIB_BITBUFFER 0
66#endif
67#if !defined(ALIB_BOXING )
68# define ALIB_BOXING 0
69#endif
70#if !defined(ALIB_TIME )
71# define ALIB_TIME 0
72#endif
73#if !defined(ALIB_CLI )
74# define ALIB_CLI 0
75#endif
76#if !defined(ALIB_CHARACTERS )
77# define ALIB_CHARACTERS 0
78#endif
79#if !defined(ALIB_CONTAINERS)
80# define ALIB_CONTAINERS 0
81#endif
82#if !defined(ALIB_CONFIGURATION)
83# define ALIB_CONFIGURATION 0
84#endif
85#if !defined(ALIB_ENUMS )
86# define ALIB_ENUMS 0
87#endif
88#if !defined(ALIB_EXPRESSIONS )
89# define ALIB_EXPRESSIONS 0
90#endif
91#if !defined(ALIB_FILES )
92# define ALIB_FILES 0
93#endif
94#if !defined(ALIB_MONOMEM )
95# define ALIB_MONOMEM 0
96#endif
97#if !defined(ALIB_SINGLETONS )
98# define ALIB_SINGLETONS 0
99#endif
100#if !defined(ALIB_STRINGS )
101# define ALIB_STRINGS 0
102#endif
103#if !defined(ALIB_CAMP )
104# define ALIB_CAMP 0
105#endif
106#if !defined( ALIB_THREADMODEL )
107# define ALIB_THREADMODEL 0
108#endif
109#if !defined( ALIB_THREADS )
110# define ALIB_THREADS 0
111#endif
112
113
114// #################################################################################################
115// Resolve module dependencies
116// #################################################################################################
117#if ALIB_ALOX
118# undef ALIB_CONFIGURATION
119# define ALIB_CONFIGURATION 1
120#endif
121#if ALIB_CLI
122# undef ALIB_CAMP
123# define ALIB_CAMP 1
124#endif
125#if ALIB_CONFIGURATION
126# undef ALIB_CAMP
127# define ALIB_CAMP 1
128#endif
129#if ALIB_EXPRESSIONS
130# undef ALIB_CAMP
131# define ALIB_CAMP 1
132#endif
133#if ALIB_FILES
134# undef ALIB_CAMP
135# define ALIB_CAMP 1
136#endif
137#if ALIB_CAMP
138# undef ALIB_STRINGS
139# define ALIB_STRINGS 1
140# undef ALIB_BOXING
141# define ALIB_BOXING 1
142# undef ALIB_CONTAINERS
143# define ALIB_CONTAINERS 1
144# undef ALIB_ENUMS
145# define ALIB_ENUMS 1
146# undef ALIB_TIME
147# define ALIB_TIME 1
148# undef ALIB_MONOMEM
149# define ALIB_MONOMEM 1
150#endif
151#if ALIB_BITBUFFER
152# undef ALIB_MONOMEM
153# define ALIB_MONOMEM 1
154# undef ALIB_CONTAINERS
155# define ALIB_CONTAINERS 1
156# undef ALIB_ENUMS
157# define ALIB_ENUMS 1
158#endif
159#if ALIB_THREADMODEL
160# undef ALIB_BOXING
161# define ALIB_BOXING 1
162# undef ALIB_CONTAINERS
163# define ALIB_CONTAINERS 1
164# undef ALIB_ENUMS
165# define ALIB_ENUMS 1
166# undef ALIB_MONOMEM
167# define ALIB_MONOMEM 1
168# undef ALIB_THREADS
169# define ALIB_THREADS 1
170#endif
171#if ALIB_ENUMS
172# undef ALIB_STRINGS
173# define ALIB_STRINGS 1
174# undef ALIB_SINGLETONS
175# define ALIB_SINGLETONS 1
176#endif
177#if ALIB_THREADS
178# undef ALIB_STRINGS
179# define ALIB_STRINGS 1
180# undef ALIB_TIME
181# define ALIB_TIME 1
182#endif
183#if ALIB_STRINGS
184# undef ALIB_CHARACTERS
185# define ALIB_CHARACTERS 1
186#endif
187#if ALIB_BOXING
188# undef ALIB_SINGLETONS
189# define ALIB_SINGLETONS 1
190# undef ALIB_CHARACTERS
191# define ALIB_CHARACTERS 1
192#endif
193
194// #################################################################################################
195// if !DOXYGEN
196// #################################################################################################
197#else
198#define ALIB_ALOX 1
199#define ALIB_BITBUFFER 1
200#define ALIB_BOXING 1
201#define ALIB_CAMP 1
202#define ALIB_CHARACTERS 1
203#define ALIB_CLI 1
204#define ALIB_CONFIGURATION 1
205#define ALIB_CONTAINERS 1
206#define ALIB_ENUMS 1
207#define ALIB_EXPRESSIONS 1
208#define ALIB_FILES 1
209#define ALIB_MONOMEM 1
210#define ALIB_SINGLETONS 1
211#define ALIB_STRINGS 1
212#define ALIB_THREADMODEL 1
213#define ALIB_THREADS 1
214#define ALIB_TIME 1
215
216#endif //!DOXYGEN
217
218// #################################################################################################
219// Macros for checking availability of modules
220// #################################################################################################
221#define ALIB_DOCUMENTATION_URL "https://alib.dev/"
222
223#define ALIB_ASSERT_MODULE(modulename) \
224static_assert( ALIB_ ## modulename, \
225 "This module is not included in the ALib distribution/built. " \
226 "See " ALIB_DOCUMENTATION_URL "alib_manual.html for more information" ); \
227
228// #################################################################################################
229// Macros to select code (without using #if/#endif)
230// #################################################################################################
231#if ALIB_ALOX
232# define IF_ALIB_ALOX(...) __VA_ARGS__
233# define IFNOT_ALIB_ALOX(...)
234#else
235# define IF_ALIB_ALOX(...)
236# define IFNOT_ALIB_ALOX(...) __VA_ARGS__
237#endif
238
239#if ALIB_BITBUFFER
240# define IF_ALIB_BITBUFFER(...) __VA_ARGS__
241# define IFNOT_ALIB_BITBUFFER(...)
242#else
243# define IF_ALIB_BITBUFFER(...)
244# define IFNOT_ALIB_BITBUFFER(...) __VA_ARGS__
245#endif
246
247#if ALIB_BOXING
248# define IF_ALIB_BOXING(...) __VA_ARGS__
249# define IFNOT_ALIB_BOXING(...)
250#else
251# define IF_ALIB_BOXING(...)
252# define IFNOT_ALIB_BOXING(...) __VA_ARGS__
253#endif
254
255#if ALIB_CHARACTERS
256# define IF_ALIB_CHARACTERS(...) __VA_ARGS__
257# define IFNOT_ALIB_CHARACTERS(...)
258#else
259# define IF_ALIB_CHARACTERS(...)
260# define IFNOT_ALIB_CHARACTERS(...) __VA_ARGS__
261#endif
262
263#if ALIB_CLI
264# define IF_ALIB_CLI(...) __VA_ARGS__
265# define IFNOT_ALIB_CLI(...)
266#else
267# define IF_ALIB_CLI(...)
268# define IFNOT_ALIB_CLI(...) __VA_ARGS__
269#endif
270
271#if ALIB_CONFIGURATION
272# define IF_ALIB_CONFIGURATION(...) __VA_ARGS__
273# define IFNOT_ALIB_CONFIGURATION(...)
274#else
275# define IF_ALIB_CONFIGURATION(...)
276# define IFNOT_ALIB_CONFIGURATION(...) __VA_ARGS__
277#endif
278
279#if ALIB_CONTAINERS
280# define IF_ALIB_CONTAINERS(...) __VA_ARGS__
281# define IFNOT_ALIB_CONTAINERS(...)
282#else
283# define IF_ALIB_CONTAINERS(...)
284# define IFNOT_ALIB_CONTAINERS(...) __VA_ARGS__
285#endif
286
287#if ALIB_ENUMS
288# define IF_ALIB_ENUMS(...) __VA_ARGS__
289# define IFNOT_ALIB_ENUMS(...)
290#else
291# define IF_ALIB_ENUMS(...)
292# define IFNOT_ALIB_ENUMS(...) __VA_ARGS__
293#endif
294
295#if ALIB_EXPRESSIONS
296# define IF_ALIB_EXPRESSIONS(...) __VA_ARGS__
297# define IFNOT_ALIB_EXPRESSIONS(...)
298#else
299# define IF_ALIB_EXPRESSIONS(...)
300# define IFNOT_ALIB_EXPRESSIONS(...) __VA_ARGS__
301#endif
302
303#if ALIB_FILES
304# define IF_ALIB_FILES(...) __VA_ARGS__
305# define IFNOT_ALIB_FILES(...)
306#else
307# define IF_ALIB_FILES(...)
308# define IFNOT_ALIB_FILES(...) __VA_ARGS__
309#endif
310
311#if ALIB_MONOMEM
312# define IF_ALIB_MONOMEM(...) __VA_ARGS__
313# define IFNOT_ALIB_MONOMEM(...)
314#else
315# define IF_ALIB_MONOMEM(...)
316# define IFNOT_ALIB_MONOMEM(...) __VA_ARGS__
317#endif
318
319#if ALIB_SINGLETONS
320# define IF_ALIB_SINGLETONS(...) __VA_ARGS__
321# define IFNOT_ALIB_SINGLETONS(...)
322#else
323# define IF_ALIB_SINGLETONS(...)
324# define IFNOT_ALIB_SINGLETONS(...) __VA_ARGS__
325#endif
326
327#if ALIB_STRINGS
328# define IF_ALIB_STRINGS(...) __VA_ARGS__
329# define IFNOT_ALIB_STRINGS(...)
330#else
331# define IF_ALIB_STRINGS(...)
332# define IFNOT_ALIB_STRINGS(...) __VA_ARGS__
333#endif
334
335#if ALIB_CAMP
336# define IF_ALIB_CAMP(...) __VA_ARGS__
337# define IFNOT_ALIB_CAMP(...)
338#else
339# define IF_ALIB_CAMP(...)
340# define IFNOT_ALIB_CAMP(...) __VA_ARGS__
341#endif
342
343#if ALIB_THREADMODEL
344# define IF_ALIB_THREADMODEL(...) __VA_ARGS__
345# define IFNOT_ALIB_THREADMODEL(...)
346#else
347# define IF_ALIB_THREADMODEL(...)
348# define IFNOT_ALIB_THREADMODEL(...) __VA_ARGS__
349#endif
350
351#if ALIB_THREADS
352# define IF_ALIB_THREADS(...) __VA_ARGS__
353# define IFNOT_ALIB_THREADS(...)
354#else
355# define IF_ALIB_THREADS(...)
356# define IFNOT_ALIB_THREADS(...) __VA_ARGS__
357#endif
358
359#if ALIB_TIME
360# define IF_ALIB_TIME(...) __VA_ARGS__
361# define IFNOT_ALIB_TIME(...)
362#else
363# define IF_ALIB_TIME(...)
364# define IFNOT_ALIB_TIME(...) __VA_ARGS__
365#endif
366
367// #################################################################################################
368// Availability of external libraries
369// #################################################################################################
370#if !defined(ALIB_EXT_LIB_THREADS_AVAILABLE)
371# define ALIB_EXT_LIB_THREADS_AVAILABLE 1
372#endif
373
374#if !defined(ALIB_FEAT_BOOST_REGEX)
375# define ALIB_FEAT_BOOST_REGEX 0
376#endif
377
378// #################################################################################################
379// Debug or release compilation
380// #################################################################################################
381#if !defined(ALIB_DEBUG)
382# if !defined(NDEBUG) || defined(_DEBUG) || defined(DEBUG)
383# define ALIB_DEBUG 1
384# else
385# define ALIB_DEBUG 0
386# endif
387#endif
388
389#if ALIB_DEBUG
390 #define ALIB_DBG(...) __VA_ARGS__
391 #define ALIB_REL(...)
392 #define ALIB_REL_DBG(releaseCode, ...) __VA_ARGS__
393#else
394 #define ALIB_DBG(...)
395 #define ALIB_REL(...) __VA_ARGS__
396 #define ALIB_REL_DBG(releaseCode, ...) releaseCode
397#endif
398
399
400
401// #################################################################################################
402// ALib Feature detection
403// (Note: this has to be done outside the module code, because the features are used with
404// the compilation verification flags below)
405// #################################################################################################
406
407// ALIB_FEAT_SINGLETON_MAPPED
408#if !defined(ALIB_FEAT_SINGLETON_MAPPED)
409# if defined(_WIN32)
410# define ALIB_FEAT_SINGLETON_MAPPED 1
411# else
412# define ALIB_FEAT_SINGLETON_MAPPED 0
413# endif
414#endif
415
416// ALIB_CHARACTERS_WIDE, ALIB_SIZEOF_WCHAR_T
417#if defined(__WCHAR_MAX__)
418 #if __WCHAR_MAX__ == 0x7FFFFFFF \
419 || __WCHAR_MAX__ == 0xFFFFFFFF
420 #define ALIB_SIZEOF_WCHAR_T 4
421 #else
422 #define ALIB_SIZEOF_WCHAR_T 2
423 #endif
424#elif defined(_MSC_VER)
425 #define ALIB_SIZEOF_WCHAR_T 2
426#else
427# define ALIB_SIZEOF_WCHAR_T 4 // guessing, will be checked below
428#endif
429
430static_assert( sizeof(wchar_t) == ALIB_SIZEOF_WCHAR_T, "Error: Platform not supported" );
431
432#if !defined(ALIB_CHARACTERS_WIDE)
433# if defined(_MSC_VER)
434# define ALIB_CHARACTERS_WIDE 1
435# else
436# define ALIB_CHARACTERS_WIDE 0
437# endif
438#endif
439
440#if !defined(ALIB_CHARACTERS_SIZEOF_WCHAR)
441# define ALIB_CHARACTERS_SIZEOF_WCHAR ALIB_SIZEOF_WCHAR_T
442#elif (ALIB_CHARACTERS_SIZEOF_WCHAR != 2) && (ALIB_CHARACTERS_SIZEOF_WCHAR != 4 )
443# error "Illegal value for symbol ALIB_CHARACTERS_SIZEOF_WCHAR given. Allowed is 2 or 4."
444#endif
445
446// Bijective boxing symbols
447#if !defined(ALIB_FEAT_BOXING_BIJECTIVE_INTEGRALS)
448# define ALIB_FEAT_BOXING_BIJECTIVE_INTEGRALS 0
449#endif
450
451#if !defined(ALIB_FEAT_BOXING_BIJECTIVE_CHARACTERS)
452# define ALIB_FEAT_BOXING_BIJECTIVE_CHARACTERS 0
453#endif
454
455#if !defined(ALIB_FEAT_BOXING_BIJECTIVE_FLOATS)
456# define ALIB_FEAT_BOXING_BIJECTIVE_FLOATS 0
457#endif
458
459// ALIB_DEBUG_ARRAY_COMPRESSION
460#if !defined(ALIB_DEBUG_ARRAY_COMPRESSION)
461# define ALIB_DEBUG_ARRAY_COMPRESSION ALIB_DEBUG
462#elif !ALIB_DEBUG && ALIB_DEBUG_ARRAY_COMPRESSION
463# undef ALIB_DEBUG_ARRAY_COMPRESSION
464# define ALIB_DEBUG_ARRAY_COMPRESSION 0
465# pragma message "Symbol ALIB_DEBUG_ARRAY_COMPRESSION set (from outside!) while ALIB_DEBUG is not. The symbol got disabled."
466#endif
467
468
469// ALIB_DEBUG_CRITICAL_SECTIONS
470#if !defined(ALIB_DEBUG_CRITICAL_SECTIONS)
471# define ALIB_DEBUG_CRITICAL_SECTIONS 0
472#elif !ALIB_DEBUG && ALIB_DEBUG_CRITICAL_SECTIONS
473# undef ALIB_DEBUG_CRITICAL_SECTIONS
474# define ALIB_DEBUG_CRITICAL_SECTIONS 0
475# pragma message "Symbol ALIB_DEBUG_CRITICAL_SECTIONS set (from outside!) while ALIB_DEBUG is not. The symbol got disabled."
476#elif !ALIB_THREADS && ALIB_DEBUG_CRITICAL_SECTIONS
477# undef ALIB_DEBUG_CRITICAL_SECTIONS
478# define ALIB_DEBUG_CRITICAL_SECTIONS 0
479# pragma message "Symbol ALIB_DEBUG_CRITICAL_SECTIONS set (from outside!) while module Threads is not included in the distribution. The symbol got disabled."
480#endif
481
482// ALIB_DEBUG_CONTAINERS
483#if !defined(ALIB_DEBUG_CONTAINERS)
484# define ALIB_DEBUG_CONTAINERS 0
485#elif !ALIB_DEBUG && ALIB_DEBUG_CONTAINERS
486# undef ALIB_DEBUG_CONTAINERS
487# define ALIB_DEBUG_CONTAINERS 0
488# pragma message "Symbol ALIB_DEBUG_CONTAINERS set (from outside!) while ALIB_DEBUG is not. The symbol got disabled."
489#endif
490
491// ALIB_DEBUG_ALLOCATIONS
492#if !defined(ALIB_DEBUG_ALLOCATIONS)
493# define ALIB_DEBUG_ALLOCATIONS 0
494#elif !ALIB_DEBUG && ALIB_DEBUG_ALLOCATIONS
495# undef ALIB_DEBUG_ALLOCATIONS
496# define ALIB_DEBUG_ALLOCATIONS 0
497# pragma message "Symbol ALIB_DEBUG_ALLOCATIONS set (from outside!) while ALIB_DEBUG is not. The symbol got disabled."
498#endif
499
500// ALIB_DEBUG_MONOMEM
501#if !defined(ALIB_DEBUG_MONOMEM)
502# define ALIB_DEBUG_MONOMEM 0
503#elif !ALIB_DEBUG && ALIB_DEBUG_MONOMEM
504# undef ALIB_DEBUG_MONOMEM
505# define ALIB_DEBUG_MONOMEM 0
506# pragma message "Symbol ALIB_DEBUG_MONOMEM set (from outside!) while ALIB_DEBUG is not. The symbol got disabled."
507#endif
508
509#if !defined(ALIB_DEBUG_BOXING)
510# define ALIB_DEBUG_BOXING 0
511#elif !ALIB_DEBUG && ALIB_DEBUG_BOXING
512# undef ALIB_DEBUG_BOXING
513# define ALIB_DEBUG_BOXING 0
514# pragma message "Symbol ALIB_DEBUG_BOXING set (from outside!) while ALIB_DEBUG is not. The symbol got disabled."
515#endif
516
517// ALIB_DEBUG_STRINGS
518#if !defined(ALIB_DEBUG_STRINGS)
519# define ALIB_DEBUG_STRINGS 0
520#elif !ALIB_DEBUG && ALIB_DEBUG_STRINGS
521# undef ALIB_DEBUG_STRINGS
522# define ALIB_DEBUG_STRINGS 0
523# pragma message "Symbol ALIB_DEBUG_STRINGS set (from outside!) while ALIB_DEBUG is not. The symbol got disabled."
524#endif
525
526// ALIB_DEBUG_RESOURCES
527#if !defined(ALIB_DEBUG_RESOURCES)
528# define ALIB_DEBUG_RESOURCES 0
529#elif !ALIB_DEBUG && ALIB_DEBUG_RESOURCES
530# undef ALIB_DEBUG_RESOURCES
531# define ALIB_DEBUG_RESOURCES 0
532# pragma message "Symbol ALIB_DEBUG_RESOURCES set (from outside!) while ALIB_DEBUG is not. The symbol got disabled."
533#endif
534
535// ALOX_DBG_LOG, ALOX_REL_LOG, ALOX_DBG_LOG_CI, ALOX_REL_LOG_CI
536#if !defined(ALOX_DBG_LOG)
537# define ALOX_DBG_LOG ALIB_DEBUG
538#endif
539#if !defined(ALOX_DBG_LOG_CI)
540# define ALOX_DBG_LOG_CI ALIB_DEBUG
541#endif
542
543#if !defined(ALOX_REL_LOG)
544# define ALOX_REL_LOG 1
545#endif
546#if !defined(ALOX_REL_LOG_CI)
547# define ALOX_REL_LOG_CI 0
548#endif
549
550// #################################################################################################
551// Compiler detection and specifics
552// #################################################################################################
553#if !DOXYGEN
554 #define DOX_MARKER(marker)
555#endif
556
557
558// GCC Compiler detection
559#if defined(__clang__)
560#elif defined(__INTEL_COMPILER) //never tested
561#elif defined(_MSC_VER)
562#elif defined(__GNUC__)
563# define ALIB_GCC 1
564#endif
565
566
567
568// --- C++ standard: set ALIB_CPP_STANDARD ---
569
570// deduce && disallow < 17
571#if defined ( _MSC_VER )
572# if _MSC_VER < 1928 // VS 2019 == VC16.8 == _MSC_VER 1928 -> C++17
573# error "ALib needs C++ standard 17. Microsoft compiler < v16.8 not supported. Compilation aborted"
574# endif
575# if defined(_MSVC_LANG)
576# if _MSVC_LANG < 201703L
577# error "ALib needs C++ standard 17. Wrong compilation settings given."
578# elif _MSVC_LANG == 201703L
579# define ALIB_INTERNAL_DEDUCED_CPPVER 17
580# elif _MSVC_LANG == 202002L
581# define ALIB_INTERNAL_DEDUCED_CPPVER 20
582# elif _MSVC_LANG > 202002L
583# define ALIB_INTERNAL_DEDUCED_CPPVER 23
584# endif
585# endif
586
587
588#elif defined(__cplusplus)
589# if __cplusplus < 201703L
590# error "ALib needs C++ 17. Compilation aborted"
591# else
592# define ALIB_INTERNAL_DEDUCED_CPPVER 17
593# endif
594# if __cplusplus == 202002L
595# undef ALIB_INTERNAL_DEDUCED_CPPVER
596# define ALIB_INTERNAL_DEDUCED_CPPVER 20
597# endif
598# if __cplusplus > 202002L
599# undef ALIB_INTERNAL_DEDUCED_CPPVER
600# define ALIB_INTERNAL_DEDUCED_CPPVER 23
601# endif
602#endif
603
604// check whether detected, given or given falsely
605#if !defined(ALIB_CPP_STANDARD)
606# if defined(ALIB_INTERNAL_DEDUCED_CPPVER)
607# define ALIB_CPP_STANDARD ALIB_INTERNAL_DEDUCED_CPPVER
608# else
609# error "Unknown compiler/toolchain. Can't deduce ALIB_CPP_STANDARD. Please provide this symbol 'manually' to the compiler."
610# endif
611#else
612# if defined(ALIB_INTERNAL_DEDUCED_CPPVER)
613# if (ALIB_CPP_STANDARD != ALIB_INTERNAL_DEDUCED_CPPVER)
614# error "ALIB_CPP_STANDARD was explicitly passed to the compiler, but does not match the language standard deduced by ALib."
615# endif
616# elif ALIB_CPP_STANDARD != 17 && ALIB_CPP_STANDARD != 20 && ALIB_CPP_STANDARD != 23
617# error "ALIB_CPP_STANDARD must be set to 17, 20 or 23."
618# endif
619#endif
620
621// final internal check
622#if ALIB_CPP_STANDARD != 17 && ALIB_CPP_STANDARD != 20 && ALIB_CPP_STANDARD != 23
623# error "Error in header. This must never happen."
624#endif
625
626// Inline code selection dependent on C++ Version
627#if ALIB_CPP_STANDARD >= 23
628# define ALIB_CPP_23(...) __VA_ARGS__
629# define ALIB_CPP_BEFORE_23(...)
630#else
631# define ALIB_CPP_23(...)
632# define ALIB_CPP_BEFORE_23(...) __VA_ARGS__
633#endif
634
635
636// Windows DLL Import/Export
637#if defined( _MSC_VER ) && !defined( ALIB_API_NO_DLL )
638 #ifdef ALIB_API_IS_DLL
639 #define ALIB_API __declspec(dllexport)
640 #else
641 #define ALIB_API __declspec(dllimport)
642 #endif
643#else
644 #define ALIB_API
645#endif
646
647
648// annotations
649#if defined( _MSC_VER )
650# define ALIB_FORCE_INLINE __forceinline
651#else
652# define ALIB_FORCE_INLINE __attribute__((always_inline)) inline
653#endif
654#define ALIB_NO_RETURN [[ noreturn ]]
655
656
657// Warnings
658#if defined(ALIB_GCC)
659
660 #define ALIB_WARNINGS_UNINITIALIZED_OFF \
661 _Pragma("GCC diagnostic push") \
662 _Pragma("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") \
663
664 #define ALIB_WARNINGS_ALLOW_NULL_POINTER_PASSING \
665 _Pragma("GCC diagnostic push") \
666 _Pragma("GCC diagnostic ignored \"-Wnonnull\"") \
667
668 #define ALIB_WARNINGS_ALLOW_UNSAFE_BUFFER_USAGE \
669 _Pragma("GCC diagnostic push") \
670
671 #define ALIB_WARNINGS_ALLOW_MACRO_REDEFINITION \
672 _Pragma("GCC diagnostic push") \
673
674 #define ALIB_WARNINGS_ALLOW_UNSAFE_FUNCTION_OR_VARIABLE \
675 _Pragma("GCC diagnostic push") \
676
677 #define ALIB_WARNINGS_MACRO_NOT_USED_OFF \
678 _Pragma("GCC diagnostic push") \
679
680 #define ALIB_WARNINGS_RESERVED_MACRO_NAME_OFF \
681 _Pragma("GCC diagnostic push") \
682
683 #define ALIB_WARNINGS_OVERLOAD_VIRTUAL_OFF \
684 _Pragma("GCC diagnostic push") \
685
686 #define ALIB_WARNINGS_ALLOW_SPARSE_ENUM_SWITCH \
687 _Pragma("GCC diagnostic push") \
688 _Pragma("GCC diagnostic ignored \"-Wswitch\"") \
689
690 #define ALIB_WARNINGS_ALLOW_BITWISE_SWITCH \
691 _Pragma("GCC diagnostic push") \
692 _Pragma("GCC diagnostic ignored \"-Wswitch\"") \
693
694 #define ALIB_WARNINGS_ALLOW_SHIFT_COUNT_OVERFLOW \
695 _Pragma("GCC diagnostic push") \
696 _Pragma("GCC diagnostic ignored \"-Wshift-count-overflow\"") \
697
698 #define ALIB_WARNINGS_IGNORE_UNUSED_MACRO \
699 _Pragma("GCC diagnostic push") \
700 _Pragma("GCC diagnostic ignored \"-Wunused-macros\"") \
701
702 #define ALIB_WARNINGS_IGNORE_UNUSED_PARAMETER \
703 _Pragma("GCC diagnostic push") \
704 _Pragma("GCC diagnostic ignored \"-Wunused-parameter\"") \
705
706 #define ALIB_WARNINGS_IGNORE_UNUSED_VARIABLE \
707 _Pragma("GCC diagnostic push") \
708 _Pragma("GCC diagnostic ignored \"-Wunused-variable\"") \
709
710 #define ALIB_WARNINGS_IGNORE_UNUSED_FUNCTION \
711 _Pragma("GCC diagnostic push") \
712 _Pragma("GCC diagnostic ignored \"-Wunused-function\"") \
713
714 #define ALIB_WARNINGS_IGNORE_UNUSED_LAMBDA_CAPTURE \
715 _Pragma("GCC diagnostic push") \
716
717 #define ALIB_WARNINGS_IGNORE_FUNCTION_TEMPLATE \
718 _Pragma("GCC diagnostic push") \
719
720 #define ALIB_WARNINGS_IGNORE_NOTHING_RETURNED \
721 _Pragma("GCC diagnostic push") \
722 _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \
723
724 #define ALIB_WARNINGS_IGNORE_INTEGRAL_CONSTANT_OVERFLOW \
725 _Pragma("GCC diagnostic push") \
726
727 #define ALIB_WARNINGS_IGNORE_RESERVED_IDENTIFIER \
728 _Pragma("GCC diagnostic push") \
729
730 #define ALIB_WARNINGS_IGNORE_DOCS \
731 _Pragma("GCC diagnostic push") \
732
733 #define ALIB_WARNINGS_IGNORE_SIGN_CONVERSION \
734 _Pragma("GCC diagnostic push") \
735 _Pragma("GCC diagnostic ignored \"-Wsign-conversion\"") \
736
737 #define ALIB_WARNINGS_IGNORE_INTEGER_OVERFLOW \
738 _Pragma("GCC diagnostic push") \
739 _Pragma("GCC diagnostic ignored \"-Wshift-count-overflow\"") \
740
741 #define ALIB_WARNINGS_RESTORE \
742 _Pragma("GCC diagnostic pop")
743
744 #if __GNUC__ < 7
745 #define ALIB_FALLTHROUGH
746 #else
747 #define ALIB_FALLTHROUGH [[gnu::fallthrough]];
748 #endif
749
750#elif defined(__clang__)
751
752 #define ALIB_WARNINGS_UNINITIALIZED_OFF \
753 _Pragma("clang diagnostic push") \
754 _Pragma("clang diagnostic ignored \"-Wuninitialized\"") \
755 _Pragma("clang diagnostic ignored \"-Wconditional-uninitialized\"") \
756
757 #define ALIB_WARNINGS_ALLOW_NULL_POINTER_PASSING \
758 _Pragma("clang diagnostic push") \
759
760 #define ALIB_WARNINGS_ALLOW_UNSAFE_BUFFER_USAGE \
761 _Pragma("clang diagnostic push") \
762 _Pragma("clang diagnostic ignored \"-Wunsafe-buffer-usage\"") \
763
764 #define ALIB_WARNINGS_OVERLOAD_VIRTUAL_OFF \
765 _Pragma("clang diagnostic push") \
766 _Pragma("clang diagnostic ignored \"-Woverloaded-virtual\"") \
767
768 #define ALIB_WARNINGS_ALLOW_MACRO_REDEFINITION \
769 _Pragma("clang diagnostic push") \
770 _Pragma("clang diagnostic ignored \"-Wmacro-redefined\"") \
771
772 #define ALIB_WARNINGS_ALLOW_UNSAFE_FUNCTION_OR_VARIABLE \
773 _Pragma("clang diagnostic push") \
774 _Pragma("clang diagnostic ignored \"-Wunused-macros\"") \
775
776
777 #define ALIB_WARNINGS_MACRO_NOT_USED_OFF \
778 _Pragma("clang diagnostic push") \
779 _Pragma("clang diagnostic ignored \"-Wunused-macros\"") \
780
781 #define ALIB_WARNINGS_RESERVED_MACRO_NAME_OFF \
782 _Pragma("clang diagnostic push") \
783 _Pragma("clang diagnostic ignored \"-Wreserved-macro-identifier\"") \
784
785 #define ALIB_WARNINGS_ALLOW_SPARSE_ENUM_SWITCH \
786 _Pragma("clang diagnostic push") \
787 _Pragma("clang diagnostic ignored \"-Wswitch\"") \
788 _Pragma("clang diagnostic ignored \"-Wswitch-enum\"") \
789
790 #define ALIB_WARNINGS_ALLOW_BITWISE_SWITCH \
791 _Pragma("clang diagnostic push") \
792 _Pragma("clang diagnostic ignored \"-Wswitch\"") \
793 _Pragma("clang diagnostic ignored \"-Wcovered-switch-default\"") \
794
795 #define ALIB_WARNINGS_ALLOW_SHIFT_COUNT_OVERFLOW \
796 _Pragma("clang diagnostic push") \
797 _Pragma("clang diagnostic ignored \"-Wshift-count-overflow\"") \
798
799 #define ALIB_WARNINGS_IGNORE_UNUSED_MACRO \
800 _Pragma("clang diagnostic push") \
801 _Pragma("clang diagnostic ignored \"-Wunused-macros\"") \
802
803 #define ALIB_WARNINGS_IGNORE_UNUSED_PARAMETER \
804 _Pragma("clang diagnostic push") \
805 _Pragma("clang diagnostic ignored \"-Wunused-parameter\"") \
806
807 #define ALIB_WARNINGS_IGNORE_UNUSED_VARIABLE \
808 _Pragma("clang diagnostic push") \
809 _Pragma("clang diagnostic ignored \"-Wunused-variable\"") \
810
811 #define ALIB_WARNINGS_IGNORE_UNUSED_FUNCTION \
812 _Pragma("clang diagnostic push") \
813 _Pragma("clang diagnostic ignored \"-Wunused-function\"") \
814 _Pragma("clang diagnostic ignored \"-Wunused-member-function\"") \
815 _Pragma("clang diagnostic ignored \"-Wunused-template\"") \
816
817 #define ALIB_WARNINGS_IGNORE_UNUSED_LAMBDA_CAPTURE \
818 _Pragma("clang diagnostic push") \
819 _Pragma("clang diagnostic ignored \"-Wunused-lambda-capture\"") \
820
821 #define ALIB_WARNINGS_IGNORE_FUNCTION_TEMPLATE \
822 _Pragma("clang diagnostic push") \
823 _Pragma("clang diagnostic ignored \"-Wunused-template\"") \
824
825 #define ALIB_WARNINGS_IGNORE_NOTHING_RETURNED \
826 _Pragma("clang diagnostic push") \
827 _Pragma("clang diagnostic ignored \"-Wreturn-type\"") \
828
829 #define ALIB_WARNINGS_IGNORE_INTEGRAL_CONSTANT_OVERFLOW \
830 _Pragma("clang diagnostic push") \
831
832 #define ALIB_WARNINGS_IGNORE_DOCS \
833 _Pragma("clang diagnostic push") \
834 _Pragma("clang diagnostic ignored \"-Wdocumentation\"") \
835
836 #define ALIB_WARNINGS_IGNORE_RESERVED_IDENTIFIER \
837 _Pragma("clang diagnostic push") \
838 _Pragma("clang diagnostic ignored \"-Wreserved-identifier\"") \
839
840 #define ALIB_WARNINGS_IGNORE_INTEGER_OVERFLOW \
841 _Pragma("clang diagnostic push") \
842 _Pragma("clang diagnostic ignored \"-Winteger-overflow\"") \
843
844 #define ALIB_WARNINGS_IGNORE_SIGN_CONVERSION \
845 _Pragma("clang diagnostic push") \
846 _Pragma("clang diagnostic ignored \"-Wsign-conversion\"") \
847
848
849 #define ALIB_WARNINGS_RESTORE \
850 _Pragma("clang diagnostic pop") \
851
852 #define ALIB_FALLTHROUGH [[clang::fallthrough]];
853
854
855#elif defined(_MSC_VER)
856 #define ALIB_WARNINGS_UNINITIALIZED_OFF \
857 __pragma(warning( push )) \
858 __pragma(warning( disable : 4701 )) \
859
860 #define ALIB_WARNINGS_ALLOW_NULL_POINTER_PASSING \
861 __pragma(warning( push )) \
862
863 #define ALIB_WARNINGS_ALLOW_UNSAFE_BUFFER_USAGE \
864 __pragma(warning( push )) \
865
866 #define ALIB_WARNINGS_MACRO_NOT_USED_OFF \
867 __pragma(warning( push )) \
868
869 #define ALIB_WARNINGS_RESERVED_MACRO_NAME_OFF \
870 __pragma(warning( push )) \
871
872 #define ALIB_WARNINGS_OVERLOAD_VIRTUAL_OFF \
873 __pragma(warning( push )) \
874
875 #define ALIB_WARNINGS_ALLOW_SPARSE_ENUM_SWITCH \
876 __pragma(warning( push )) \
877
878 #define ALIB_WARNINGS_ALLOW_SPARSE_ENUM_SWITCH \
879 __pragma(warning( push )) \
880
881 #define ALIB_WARNINGS_ALLOW_MACRO_REDEFINITION \
882 __pragma(warning( push )) \
883 __pragma(warning( disable : 4005 )) \
884
885 #define ALIB_WARNINGS_ALLOW_UNSAFE_FUNCTION_OR_VARIABLE \
886 __pragma(warning( push )) \
887 __pragma(warning( disable : 4996 )) \
888
889 #define ALIB_WARNINGS_ALLOW_BITWISE_SWITCH \
890 __pragma(warning( push )) \
891
892 #define ALIB_WARNINGS_ALLOW_SHIFT_COUNT_OVERFLOW \
893 __pragma(warning( push )) \
894
895 #define ALIB_WARNINGS_IGNORE_UNUSED_MACRO \
896 __pragma(warning( push )) \
897
898 #define ALIB_WARNINGS_IGNORE_UNUSED_PARAMETER \
899 __pragma(warning( push )) \
900
901 #define ALIB_WARNINGS_IGNORE_UNUSED_VARIABLE \
902 __pragma(warning( push )) \
903
904 #define ALIB_WARNINGS_IGNORE_UNUSED_FUNCTION \
905 __pragma(warning( push )) \
906
907 #define ALIB_WARNINGS_IGNORE_UNUSED_LAMBDA_CAPTURE \
908 __pragma(warning( push )) \
909
910 #define ALIB_WARNINGS_IGNORE_FUNCTION_TEMPLATE \
911 __pragma(warning( push )) \
912
913 #define ALIB_WARNINGS_IGNORE_NOTHING_RETURNED \
914 __pragma(warning( push )) \
915 __pragma(warning( disable : 4715 )) \
916
917 #define ALIB_WARNINGS_IGNORE_INTEGRAL_CONSTANT_OVERFLOW \
918 __pragma(warning( push )) \
919 __pragma(warning( disable : 4305 )) \
920 __pragma(warning( disable : 4307 )) \
921 __pragma(warning( disable : 4309 )) \
922 __pragma(warning( disable : 4310 )) \
923 __pragma(warning( disable : 4293 )) \
924
925 #define ALIB_WARNINGS_IGNORE_INTEGER_OVERFLOW \
926 __pragma(warning( push )) \
927 __pragma(warning( disable : 4293 )) \
928
929 #define ALIB_WARNINGS_IGNORE_RESERVED_IDENTIFIER \
930 __pragma(warning( push )) \
931
932 #define ALIB_WARNINGS_IGNORE_DOCS \
933 __pragma(warning( push )) \
934
935 #define ALIB_WARNINGS_IGNORE_SIGN_CONVERSION \
936 __pragma(warning( push )) \
937
938 #define ALIB_WARNINGS_IGNORE_DOCS \
939 __pragma(warning( push )) \
940
941 #define ALIB_WARNINGS_RESTORE \
942 __pragma(warning( pop )) \
943
944 #define ALIB_FALLTHROUGH
945
946#else
947 #define ALIB_WARNINGS_RESTORE
948 #define ALIB_FALLTHROUGH
949#endif
950
951// #################################################################################################
952// Preprocessor tools
953// #################################################################################################
954#if DOXYGEN
955# define ALIB_NSTRINGIFY(a)
956# define ALIB_STRINGIFY(a)
957#else
958# define ALIB_STRINGIFY_X(a) A_CHAR( #a )
959# define ALIB_STRINGIFY(a) ALIB_STRINGIFY_X(a)
960# define ALIB_NSTRINGIFY_X(a) #a
961# define ALIB_NSTRINGIFY(a) ALIB_NSTRINGIFY_X(a)
962#endif
963
964// Note: The double expansion ensures that if another macro is given, e.g., "__LINE__", it is
965// expanded before it is concatenated.
966#if !DOXYGEN
967#define ALIB_CONCAT_IMPL(a,b) a ## b
968#endif
969#define ALIB_CONCAT(a,b) ALIB_CONCAT_IMPL(a,b)
970
971#if defined(__clang__)
972# define ALIB_IDENTIFIER(prefix) ALIB_WARNINGS_IGNORE_RESERVED_IDENTIFIER \
973 ALIB_CONCAT(prefix, __LINE__) \
974 ALIB_WARNINGS_RESTORE
975#else
976# define ALIB_IDENTIFIER(prefix) ALIB_CONCAT(prefix, __LINE__)
977#endif
978
979#define ALIB_EMPTY
980
981
982#define ALIB_COMMA ,
983#if ALIB_DEBUG
984# define ALIB_COMMA_DBG ,
985#else
986# define ALIB_COMMA_DBG
987#endif
988
989// Macros for writing "nicer" static_assert messages
990#define ALIB_STATIC_ASSERT( CondVariable, Cond, Message ) \
991{ constexpr bool CondVariable= Cond; \
992 static_assert( CondVariable, Message ); } \
993
994#define ALIB_STATIC_DENY( CondVariable, Cond, Message ) \
995{ constexpr bool CondVariable= !(Cond); \
996 static_assert( CondVariable, Message ); } \
997
998//==================================================================================================
999/// Used with macro \ref ALIB_ASSERT_GLOBAL_NAMESPACE for testing.
1000//==================================================================================================
1001struct ALibTestGlobalNamespace;
1002#define ALIB_ASSERT_GLOBAL_NAMESPACE \
1003struct ALibTestGlobalNamespace; \
1004static_assert(std::is_same<ALibTestGlobalNamespace, ::ALibTestGlobalNamespace>::value, \
1005 "This is not the global namespace!");
1006
1007// #################################################################################################
1008// Copies of command line arguments of the process
1009// #################################################################################################
1010namespace alib {
1011 /// The number of command line arguments. Defaults to \c 0.
1012 /// \note An application is responsible for setting this global variable in its <c>main()</c>
1013 /// function, in case the value is needed somewhere.
1014 ALIB_API extern int ARG_C;
1015
1016 /// List of command line arguments if given as single byte character strings.
1017 /// \note An application is responsible for setting this global variable in its <c>main()</c>
1018 /// function, in case the value is needed somewhere.
1019 ALIB_API extern const char** ARG_VN;
1020
1021 /// List of command line arguments if given as multi-byte character strings.
1022 /// \note An application is responsible for setting this global variable in its <c>main()</c>
1023 /// function, in case the value is needed somewhere.
1024 ALIB_API extern const wchar_t** ARG_VW;
1025} // namespace [alib]
1026
1027// #################################################################################################
1028// Other tools
1029// #################################################################################################
1030#define ALIB_STACK_ALLOCATED_TYPE(T) \
1031private: void* operator new (size_t); \
1032 void* operator new (size_t, void*); \
1033 void* operator new[](size_t); \
1034 void* operator new[](size_t, void*); \
1035 T(const T& ); \
1036 T( T&& ); \
1037 void operator=(const T& ); \
1038 void operator=( T&& );
1039
1040#include <type_traits>
1041namespace alib::lang {
1042
1043#if DOXYGEN
1044 /// Checks if a given object equals a default-constructed value of the same type.
1045 /// This function is useful with types that are not otherwise testable, for example,
1046 /// type <c>std::thread::id</c>.
1047 /// @param t The instance to test.
1048 /// @return \c true if \p{t} is default-constructed, \c false otherwise.
1049 template<typename T> inline constexpr bool IsNull(const T& t);
1050
1051 /// The negation of #alib::lang::IsNull.
1052 /// @param t The instance to test.
1053 /// @return \c false if \p{t} is default-constructed, \c true otherwise.
1054 template<typename T> inline constexpr bool IsNotNull(const T& t) { return t==T(); }
1055
1056 /// Assigns a default-constructed value to the given instance.
1057 /// This function is useful with types that are not otherwise nullable, for example,
1058 /// type <c>std::thread::id</c>.
1059 /// @param t The instance to test.
1060 template<typename T> inline constexpr void SetNull(const T& t);
1061#else
1062 template<typename T>
1063 inline constexpr
1064 typename std::enable_if_t<std::is_default_constructible_v<T>,bool>
1065 IsNull(const T& t) { return t==T(); }
1066
1067 template<typename T>
1068 inline constexpr
1069 typename std::enable_if_t<std::is_default_constructible_v<T>,bool>
1070 IsNotNull(const T& t) { return t!=T(); }
1071
1072 template<typename T>
1073 inline constexpr
1074 typename std::enable_if_t<std::is_default_constructible_v<T>,void>
1075 SetNull(T& t) { t= T(); }
1076#endif
1077} // namespace [alib::lang]
1078
1079namespace alib {
1080/// This tag-type is used accross \alib to indicate that no check of the input parameters should be
1081/// performed.
1082/// Methods affected expose a template parameter named \p{TCheck} which usually defaults to
1083/// this types' counterpart \alib{CHK}.
1084///
1085/// For example, various methods of the \alib string types, which perform range-checks on
1086/// string-indices, use this template parameter.
1087/// With debug-compilations the checks are still made, and if they fail, the parameters are not
1088/// corrected, but instead an \alib assertion is raised.
1089/// In release builds, however, no checks are performed, which improves execution speed.
1090///
1091/// A programmer does not notice the existence of this option, unless he consults the corresponding
1092/// method's reference documentation, because of the default-value \alib{CHK}.
1093/// Only with code critical to performance or size, the parameter might be crucial to give.
1094struct NC : public std::false_type {};
1095
1096/// See sibling type \alib{NC}.
1097struct CHK : public std::true_type {};
1098
1099
1100} // namespace [alib]
1101
1102// #################################################################################################
1103// Debug Messages and Assertions
1104// #################################################################################################
1105#if ALIB_EXT_LIB_THREADS_AVAILABLE
1106# include <thread>
1107#endif
1108#include <typeinfo>
1109
1110namespace alib { namespace lang {
1111 /// A simple struct that holds source code location information.
1112 /// Usually, this is information about a caller of a function, used with debug-compilations.
1113 /// Module \alib_alox might be explicitly compiled to include such caller information also in
1114 /// release-versions of software.
1115 ///
1116 ///
1117 /// @see
1118 /// - Chapter \ref alib_manual_appendix_callerinfo of the General Programmer's Manual.
1119 /// - Macros \ref ALIB_CALLER, \ref ALIB_CALLER_PRUNED, \ref ALIB_COMMA_CALLER_PRUNED and
1120 /// \ref ALIB_CALLER_NULLED.
1121 /// - Instances of this type are appendable to class \b AString in a default way.
1122 /// This is implemented with functor
1123 /// \alib{strings::APPENDABLES;T_Append<lang::CallerInfo,TChar,TAllocator>}.
1124 /// - Class \alib{lang::format;FMTCallerInfo} defines a format specification to customize
1125 /// the output.
1126 /// As always, \alib{lang::format;FMTCallerInfo;that syntax} is directly available in
1127 /// placeholder fields of class \alib{lang::format;FormatterPythonStyle}.
1129 {
1130 const char* File{nullptr}; ///< The name of the source file as given by compiler.
1131 int Line{0}; ///< The line number within #File.
1132 const char* Func{nullptr}; ///< The function name of the source location. Nulled if
1133 ///< the location is not inside a function or method.
1134 ///
1135 #if ALIB_EXT_LIB_THREADS_AVAILABLE
1136 std::thread::id ThreadID; ///< The ID of the calling thread.
1137 #endif
1138 const std::type_info* TypeInfo{nullptr}; ///< The calling type.
1139 };
1140} // namespace alib[::lang]
1141
1142/// Type alias in namespace \b alib.
1144
1145// DbgAssertSingleThreaded()
1146#if !DOXYGEN
1147# if ALIB_DEBUG && !ALIB_THREADS && ALIB_EXT_LIB_THREADS_AVAILABLE
1149# else
1150 inline void DbgAssertSingleThreaded() {} // optimized out
1151# endif
1152#endif
1153} // namespace [alib]
1154
1155
1156// Macros for passing source code information
1157#if defined ( _MSC_VER )
1158# define ALIB_CALLER_FUNC __FUNCTION__
1159#else
1160# define ALIB_CALLER_FUNC __func__
1161#endif
1162
1163#if ALIB_EXT_LIB_THREADS_AVAILABLE
1164# define ALIB_CALLER {__FILE__,__LINE__,ALIB_CALLER_FUNC,::std::this_thread::get_id(),&typeid(*this)}
1165#else
1166# define ALIB_CALLER {__FILE__,__LINE__,ALIB_CALLER_FUNC,&typeid(*this)}
1167#endif
1168
1169#if ALIB_DEBUG
1170# define ALIB_CALLER_PRUNED ALIB_CALLER
1171# define ALIB_COMMA_CALLER_PRUNED , ALIB_CALLER
1172# define ALIB_CALLER_PRUNED_COMMA ALIB_CALLER ,
1173# define ALIB_CALLER_NULLED ALIB_CALLER
1174# define ALIB_COMMA_CALLER_NULLED , ALIB_CALLER
1175# define ALIB_CALLER_NULLED_COMMA ALIB_CALLER ,
1176# define ALIB_DBG_TAKE_CI const CallerInfo& ci
1177#else
1178# define ALIB_CALLER_PRUNED
1179# define ALIB_COMMA_CALLER_PRUNED
1180# define ALIB_CALLER_PRUNED_COMMA
1181# if ALIB_EXT_LIB_THREADS_AVAILABLE
1182# define ALIB_CALLER_NULLED {nullptr,0,nullptr,::std::thread::id(), nullptr}
1183# define ALIB_COMMA_CALLER_NULLED , {nullptr,0,nullptr,::std::thread::id(), nullptr}
1184# define ALIB_CALLER_NULLED_COMMA {nullptr,0,nullptr,::std::thread::id(), nullptr} ,
1185# else
1186# define ALIB_CALLER_NULLED {nullptr,0,nullptr,nullptr}
1187# define ALIB_COMMA_CALLER_NULLED , {nullptr,0,nullptr,nullptr}
1188# define ALIB_CALLER_NULLED_COMMA {nullptr,0,nullptr,nullptr} ,
1189# endif
1190# define ALIB_DBG_TAKE_CI
1191#endif
1192
1193// #################################################################################################
1194// Debug Messages and Assertions
1195// #################################################################################################
1196#if ALIB_DEBUG
1197#if !defined (_ASSERT_H) && !defined(assert)
1198# include <assert.h>
1199#endif
1200namespace alib::lang {
1201/// Some \alib modules do not (must not) rely on \alib{lang;Report} /
1202/// \alib{lang;ReportWriter} mechanics. Therefore, this simple method is
1203/// used for error handling in those portions of \alib that are exposed in such modules.<br>
1204/// This method first checks if static function pointer \alib{lang::DBG_SIMPLE_ALIB_MSG_PLUGIN} is set
1205/// and if yes, passes the parameters to this method and exits.
1206/// If the module \alib_basecamp is included in the \alibdist, method \alib{lang::basecamp;BaseCamp::bootstrap}
1207/// sets this plug-in function to a custom one which passes the message(s) to a proper
1208/// \alib{lang;Report;ALib Report}.
1209///
1210/// Otherwise, the method just writes to the standard output stream and then, if \p{type} equals
1211/// \c 0, invokes <c>assert(0)</c>.
1212///
1213/// @param ci Caller information.
1214/// @param type The type of the message. The default implementation does not use this, other
1215/// than invoking <c>assert(0)</c> in the case this parameter equals \c 0.
1216/// @param topic The topic of the message.
1217/// @param msg1 The first message string.
1218/// @param msg2 Optional 2nd message string.
1219/// @param msg3 Optional 3rd message string.
1220/// @param msg4 Optional 4th message string.
1221/// @param msg5 Optional 5th message string.
1223extern void DbgSimpleALibMsg( const CallerInfo& ci, int type, const char* topic,
1224 const char* msg1= nullptr,
1225 const char* msg2= nullptr,
1226 const char* msg3= nullptr,
1227 const char* msg4= nullptr,
1228 const char* msg5= nullptr );
1229
1230/// Overloaded version of
1231/// \ref DbgSimpleALibMsg(const CallerInfo& ci,int,const char*,const char*,const char*,const char*,const char*,const char*) "DbgSimpleALibMsg"
1232/// which accepts one integral value and writes \p{msg} and \p{intValue} in sequence.
1233///
1234/// @param ci Caller information.
1235/// @param type The type of the message. The default implementation does not use this, other
1236/// than invoking <c>assert(0)</c> in the case this parameter equals \c 0.
1237/// @param topic The topic of the report.
1238/// @param msg The message string.
1239/// @param intValue An integer parameter (optional due to overload).
1240///
1242extern void DbgSimpleALibMsg( const CallerInfo& ci,
1243 int type,
1244 const char* topic,
1245 const char* msg,
1246 const int intValue );
1247
1248/// This function pointer defaults to \c nullptr and may be set to replace function
1249/// #DbgSimpleALibMsg.
1250/// With the use of \alib_basecamp, the module's bootstrap code (precisely method
1251/// \alib{lang::basecamp;BaseCamp::bootstrap}) sets this pointer to a small method which creates an
1252/// \alib{lang;Report} on the default \alib{lang;ReportWriter}.
1253///
1254/// - \p{ci}: Information about the scope of invocation.
1255/// - \p{type}: The type of the message. As a convention, 0 is severe error, others are warning levels.
1256/// - \p{qtyMsgs}: The number of messages passed.
1257/// - \p{msgs}: The message strings.
1258extern void (*DBG_SIMPLE_ALIB_MSG_PLUGIN)( const CallerInfo& ci,
1259 int type , const char* topic,
1260 int qtyMsgs, const char** msgs );
1261
1262
1263} // namespace [alib::lang]
1264#endif // ALIB_DEBUG
1265
1266#if ALIB_DEBUG
1267#define ALIB_ERROR( ...) { alib::lang::DbgSimpleALibMsg( ALIB_CALLER_PRUNED , 0, __VA_ARGS__); }
1268#define ALIB_WARNING( ...) { alib::lang::DbgSimpleALibMsg( ALIB_CALLER_PRUNED , 1, __VA_ARGS__); }
1269#define ALIB_MESSAGE( ...) { alib::lang::DbgSimpleALibMsg( ALIB_CALLER_PRUNED , 2, __VA_ARGS__); }
1270#define ALIB_ASSERT( cond) { if( !( cond)) ALIB_ERROR ( "Assertion Failed" ); }
1271#define ALIB_ASSERT_ERROR( cond, ...) { if( !( cond)) ALIB_ERROR ( __VA_ARGS__ ); }
1272#define ALIB_ASSERT_WARNING( cond, ...) { if( !( cond)) ALIB_WARNING ( __VA_ARGS__ ); }
1273#define ALIB_ASSERT_MESSAGE( cond, ...) { if( !( cond)) ALIB_MESSAGE ( __VA_ARGS__ ); }
1274
1275#else // ALIB_DEBUG
1276 #define ALIB_ERROR( ... ) { }
1277 #define ALIB_WARNING( ... ) { }
1278 #define ALIB_MESSAGE( ... ) { }
1279 #define ALIB_ASSERT( cond ) { }
1280 #define ALIB_ASSERT_ERROR( cond, ...) { }
1281 #define ALIB_ASSERT_WARNING( cond, ...) { }
1282 #define ALIB_ASSERT_MESSAGE( cond, ...) { }
1283#endif
1284
1285#if ALIB_DEBUG
1286 #define ALIB_ASSERT_RESULT_EQUALS( func, value ) { auto result= func; assert(result == value); ((void) result); }
1287 #define ALIB_ASSERT_RESULT_NOT_EQUALS( func, value ) { auto result= func; assert(result != value); ((void) result); }
1288 #define ALIB_ASSERT_RESULT_GREATER_THAN(func, value ) { auto result= func; assert(result > value); ((void) result); }
1289 #define ALIB_ASSERT_RESULT_LESS_THAN( func, value ) { auto result= func; assert(result < value); ((void) result); }
1290#else
1291 #define ALIB_ASSERT_RESULT_EQUALS( func, value ) { func; }
1292 #define ALIB_ASSERT_RESULT_NOT_EQUALS( func, value ) { func; }
1293 #define ALIB_ASSERT_RESULT_GREATER_THAN(func, value ) { func; }
1294 #define ALIB_ASSERT_RESULT_LESS_THAN( func, value ) { func; }
1295#endif
1296
1297
1298// #################################################################################################
1299// Bootstrapping & Shutdown
1300// #################################################################################################
1301
1302// #################################################################################################
1303// Compilation flags
1304// Create a bitset from the ALib compilation features.
1305// For this, we ensure that the individual headers tested are included
1306// #################################################################################################
1307
1308namespace alib {
1309 /// This is a simple copyable set of bits comprising the compilation flags.
1310 /// @see Used with methods \alib{Bootstrap} which calls \alib{AssertALibVersionAndFlags}.
1312 {
1313 unsigned char bits[6]; ///< The Flags.
1314 };
1315}
1316
1317#if !DOXYGEN
1318# define ALIB_COMPILATION_FLAGS \
1319 + (1<<0) * ALIB_ALOX \
1320 + (1<<1) * ALIB_BITBUFFER \
1321 + (1<<2) * ALIB_BOXING \
1322 + (1<<3) * ALIB_CAMP \
1323 + (1<<4) * ALIB_CHARACTERS \
1324 + (1<<5) * ALIB_CLI \
1325 + (1<<6) * ALIB_CONFIGURATION \
1326 + (1<<7) * ALIB_CONTAINERS \
1327, \
1328 + (1<<0) * ALIB_ENUMS \
1329 + (1<<1) * ALIB_EXPRESSIONS \
1330 + (1<<2) * ALIB_FILES \
1331 + (1<<3) * ALIB_MONOMEM \
1332 + (1<<4) * ALIB_SINGLETONS \
1333 + (1<<5) * ALIB_STRINGS \
1334 + (1<<6) * ALIB_THREADMODEL \
1335 + (1<<7) * ALIB_THREADS \
1336, \
1337 + (1<<0) * ALIB_TIME \
1338 + (1<<7) * ALIB_DEBUG \
1339, \
1340 + (1<<0) * ALIB_DEBUG_ARRAY_COMPRESSION \
1341 + (1<<1) * ALIB_DEBUG_ALLOCATIONS \
1342 + (1<<2) * ALIB_DEBUG_BOXING \
1343 + (1<<3) * ALIB_DEBUG_CONTAINERS \
1344 + (1<<4) * ALIB_DEBUG_CRITICAL_SECTIONS \
1345 + (1<<5) * ALIB_DEBUG_MONOMEM \
1346 + (1<<6) * ALIB_DEBUG_STRINGS \
1347 + (1<<7) * ALIB_DEBUG_RESOURCES \
1348, \
1349 + (1<<0) * ALIB_FEAT_SINGLETON_MAPPED \
1350 + (1<<1) * ALIB_CHARACTERS_WIDE \
1351 + (1<<2) * (ALIB_CHARACTERS_SIZEOF_WCHAR == 4 ? 1 : 0) \
1352 + (1<<3) * ALIB_FEAT_BOXING_BIJECTIVE_INTEGRALS \
1353 + (1<<4) * ALIB_FEAT_BOXING_BIJECTIVE_CHARACTERS \
1354 + (1<<5) * ALIB_FEAT_BOXING_BIJECTIVE_FLOATS \
1355 + (1<<6) * ALIB_FEAT_BOOST_REGEX \
1356, \
1357 + (1<<0) * ALOX_DBG_LOG \
1358 + (1<<1) * ALOX_DBG_LOG_CI \
1359 + (1<<2) * ALOX_REL_LOG \
1360 + (1<<3) * ALOX_REL_LOG_CI \
1361
1362#endif //ALIB_DOX
1363
1364namespace alib {
1365
1366/// State of initialization of the \alibmods that do not dispose over a \alib{lang::Camp}.
1367/// instance.
1368extern bool NonCampModulesInitialized;
1369
1370/// Performs standard bootstrapping of \alib. All details are explained
1371/// in chapter \ref alib_manual_bootstrapping of the \ref alib_manual.
1372///
1373/// \note In addition, function \ref alib::AssertALibVersionAndFlags is invoked.
1374/// For this, the parameters of this function must not be given, but left to their
1375/// default values, which are read from corresponding preprocessor symbols.<br>
1376/// For more information on this topic, see chapter
1377/// \ref alib_manual_bootstrapping_assertcomp of the \ref alib_manual.
1378///
1379/// @param alibVersion The \alib version used by the caller.
1380/// Defaults to \ref ALIB_VERSION and \b must not be passed.
1381/// @param alibRevision The \alib sub-version used by the caller.
1382/// Defaults to \ref ALIB_REVISION and \b must not be passed.
1383/// @param compilationFlags The flags as defined in invoking compilation unit.
1384/// Defaults to
1385/// \doxlinkproblem{group__GrpALibPreproMacros.html;gaac71b6511690f5af0abf5213b0434111;ALIB_COMPILATION_FLAGS;ALIB_COMPILATION_FLAGS}
1386/// and \b must not be passed.
1387ALIB_API void Bootstrap(int alibVersion = ALIB_VERSION,
1388 int alibRevision = ALIB_REVISION,
1389 TCompilationFlags compilationFlags = TCompilationFlags{ALIB_COMPILATION_FLAGS});
1390
1391/// Initialization levels usable with \ref alib_manual_bootstrapping_camps "Bootstrapping ALib Camps".
1393{
1394 /// Field \alib{lang;Camp::resourcePool} is created when this phase is called for a camp.
1395 /// Camps are requested to feed in their resources now. When this is done, all entities that
1396 /// rely exclusively on resources are to be initialized. For example, all resourced enumerations
1397 /// of a camp should be parsed in this phase.
1398 PrepareResources = 1,
1399
1400 /// Field \alib{lang;Camp::config} is created when this phase is called for a camp.
1401 /// Camps are requested to
1402 /// \alib{config;Configuration::RegisterType;register application specific variable types} in
1403 /// this phase. Furthermore modifications on the configuration object itself might be performed,
1404 /// for example \alib{config;ConfigurationPlugin;custom plugins} might be added to a
1405 /// configuration or configurable options of default plug-ins can be set.<br>
1406 /// Finally, this is the right phase to
1407 /// \alib{config;Configuration::PreloadVariables;declare variables} which have a resourced
1408 /// variable declaration, or likewise perform 'hard-coded' variable declarations including
1409 /// their default values.
1410 PrepareConfig = 2,
1411
1412 /// The final initialization phase. Here, camps are initializing their custom setup.
1413 Final = 3,
1414};
1415
1416/// Termination levels usable with \ref alib_manual_bootstrapping_camps "Bootstrapping ALib Camps".
1418{
1419 Announce = 1, ///< Signals termination. Keeps resources, config, etc.
1420 ///< intact. Usable to write configuration data, stop
1421 ///< background threads, etc.
1422 Destruct = 2, ///< The main phase of termination that destructs everything.
1423};
1424
1425// forwards
1426namespace lang { class Camp; }
1427ALIB_API void Bootstrap(BootstrapPhases targetPhase,
1428 lang::Camp* targetCamp = nullptr,
1429 int alibVersion = ALIB_VERSION,
1430 int alibRevision = ALIB_REVISION,
1431 TCompilationFlags compilationFlags = TCompilationFlags{ALIB_COMPILATION_FLAGS} );
1432
1433ALIB_API void Shutdown (ShutdownPhases targetPhase,
1434 lang::Camp* targetCamp = nullptr );
1435
1436
1437
1438/// Terminates \alib. All details are explained
1439/// in chapter \ref alib_manual_bootstrapping of the \ref alib_manual.
1440ALIB_API void Shutdown();
1441
1442
1443/// This is a struct composing an entry in #COMPILATION_FLAG_MEANINGS.
1445{
1446 int Flag; ///< The bit number in the bitset.
1447 const char* Name; ///< The human-readable meaning of the bit.
1448};
1449
1450/// This is for the creation of output on information about the bits found in
1451/// field #COMPILATION_FLAGS.
1452/// Declared public to allow exposure, e.g., in verbose logging.
1453/// \see Method #AssertALibVersionAndFlags for more information.
1454extern ALIB_API
1456
1457
1458/// The module version. Standard \alib versioning scheme is YYMM (as integer number)
1459/// of the module release date.
1460/// Besides this version number, field #REVISION indicates if this is a revised version
1461/// of a former release.
1462extern ALIB_API
1463int VERSION;
1464
1465/// The revision number of this release. Usually a module is initially released as
1466/// revision \e 0. Pure bug-fix releases that do not change the interface of \alib
1467/// are holding the same #VERSION but an increased number in this field.
1468extern ALIB_API
1469unsigned char REVISION;
1470
1471/// These flags are used internally to detect incompatibilities when linking \alib to binaries that
1472/// use different compilation flags. Declared public to allow exposure, e.g., in verbose logging.
1473/// \see Function #AssertALibVersionAndFlags, which is invoked by overloaded functions
1474/// #Bootstrap.
1475extern ALIB_API
1477
1478
1479
1480//==================================================================================================
1481/// Compares a given set of compilation flags with the ones set in the \alib library.
1482/// If a mismatch is found, the configuration mismatch is written to <c>std::cerr</c>
1483/// and <c>exit(255)</c> is performed.
1484///
1485/// This function called in all variants of function \ref alib::Bootstrap.
1486/// If a using application wants to act different on such a mismatch, an own check of
1487/// global variables \ref alib::VERSION, \ref alib::REVISION and \ref alib::COMPILATION_FLAGS against
1488/// preprocessor symbols \ref ALIB_VERSION, \ref ALIB_REVISION and
1489/// \doxlinkproblem{group__GrpALibPreproMacros.html;gaac71b6511690f5af0abf5213b0434111;ALIB_COMPILATION_FLAGS;ALIB_COMPILATION_FLAGS}
1490/// has to be performed \e before calling \b Bootstrap.
1491///
1492/// \attention A mismatch in \alib library version and compilation flags, may lead to very
1493/// dubious misbehavior which is almost impossible to debug. This is true for any
1494/// C/C++ software/library mismatch.
1495///
1496/// @param alibVersion The \alib version required.
1497/// Defaults to \ref ALIB_VERSION and \b must not be passed when invoking
1498/// this function.
1499/// @param alibRevision The \alib sub-version required.
1500/// Defaults to \ref ALIB_REVISION and \b must not be passed when invoking
1501/// this function.
1502/// @param compilationFlags The flags as defined in invoking compilation unit.
1503/// Defaults to \c ALIB_COMPILATION_FLAGS and \b must not be given.
1504///
1505//==================================================================================================
1507void AssertALibVersionAndFlags( int alibVersion = ALIB_VERSION,
1508 int alibRevision = ALIB_REVISION,
1509 TCompilationFlags compilationFlags= TCompilationFlags{ALIB_COMPILATION_FLAGS} );
1510
1511} // namespace [alib]
1512
1513
1514#endif // HPP_ALIB
1515
#define ALIB_REVISION
Definition alib.hpp:25
#define ALIB_VERSION
Definition alib.hpp:24
#define ALIB_SIZEOF_WCHAR_T
Definition alib.hpp:420
#define ALIB_API
Definition alib.hpp:639
constexpr bool IsNotNull(const T &t)
Definition alib.hpp:1054
constexpr bool IsNull(const T &t)
constexpr void SetNull(const T &t)
ALIB_API void DbgSimpleALibMsg(const CallerInfo &ci, int type, const char *topic, const char *msg1=nullptr, const char *msg2=nullptr, const char *msg3=nullptr, const char *msg4=nullptr, const char *msg5=nullptr)
void(* DBG_SIMPLE_ALIB_MSG_PLUGIN)(const CallerInfo &ci, int type, const char *topic, int qtyMsgs, const char **msgs)
Definition alib.cpp:316
Definition alib.cpp:69
ShutdownPhases
Termination levels usable with Bootstrapping ALib Camps.
Definition alib.hpp:1418
@ Destruct
The main phase of termination that destructs everything.
ALIB_WARNINGS_ALLOW_UNSAFE_BUFFER_USAGE void AssertALibVersionAndFlags(int alibVersion, int alibRevision, TCompilationFlags compilationFlags)
Definition alib.cpp:184
CompilationFlagMeaningsEntry COMPILATION_FLAG_MEANINGS[37]
Definition alib.cpp:135
BootstrapPhases
Initialization levels usable with Bootstrapping ALib Camps.
Definition alib.hpp:1393
@ Final
The final initialization phase. Here, camps are initializing their custom setup.
bool NonCampModulesInitialized
Definition alib.cpp:75
const char ** ARG_VN
Definition alib.cpp:72
int ARG_C
Definition alib.cpp:71
ALIB_WARNINGS_RESTORE void Bootstrap(int alibVersion, int alibRevision, TCompilationFlags compilationFlags)
Definition alib.cpp:84
unsigned char REVISION
Definition alib.cpp:78
void Shutdown()
Definition alib.cpp:122
const wchar_t ** ARG_VW
Definition alib.cpp:73
void DbgAssertSingleThreaded()
Definition alib.cpp:267
ALIB_WARNINGS_ALLOW_UNSAFE_BUFFER_USAGE TCompilationFlags COMPILATION_FLAGS
Definition alib.cpp:80
int VERSION
Definition alib.cpp:77
See sibling type NC.
Definition alib.hpp:1097
This is a struct composing an entry in COMPILATION_FLAG_MEANINGS.
Definition alib.hpp:1445
const char * Name
The human-readable meaning of the bit.
Definition alib.hpp:1447
int Flag
The bit number in the bitset.
Definition alib.hpp:1446
unsigned char bits[6]
The Flags.
Definition alib.hpp:1313
std::thread::id ThreadID
The ID of the calling thread.
Definition alib.hpp:1136
const char * Func
Definition alib.hpp:1132
const std::type_info * TypeInfo
The calling type.
Definition alib.hpp:1138
int Line
The line number within File.
Definition alib.hpp:1131