ALib C++ Library
Library Version: 2402 R1
Documentation generated by doxygen
Loading...
Searching...
No Matches
integers.hpp
Go to the documentation of this file.
1/** ************************************************************************************************
2 * \file
3 * This header file is part of the \aliblong. It does not belong to an \alibmod and is
4 * included in any \alibdist.
5 *
6 * \emoji :copyright: 2013-2024 A-Worx GmbH, Germany.
7 * Published under \ref mainpage_license "Boost Software License".
8 **************************************************************************************************/
9#ifndef HPP_ALIB_LANG_INTEGERS
10#define HPP_ALIB_LANG_INTEGERS 1
11
12#if !defined(HPP_ALIB) && !defined(ALIB_DOX)
13# include "alib/alib.hpp"
14#endif
15
16#if !defined (_GLIBCXX_CSTDINT) && !defined (_CSTDINT_)
17# include <cstdint>
18#endif
19
20#if !defined (_GLIBCXX_CSTDDEF) && !defined (_CSTDDEF_)
21# include <cstddef>
22#endif
23
24namespace alib { namespace lang {
25
26// #################################################################################################
27// types integer, uinteger, intGap_t and uintGap_t
28// #################################################################################################
29#if defined(ALIB_DOX)
30
31 #define ALIB_SIZEOF_INTEGER
32
33/**
34 * This type specifies platform independent integral values of the 'natural' bit-size of the
35 * underlying platform. In general, on 32-bit systems this will be 32-bit wide, on 64-bit systems,
36 * 64-bits. Hence, on standard architectures, it has the same bit-size and signedness as
37 * \b std::ptrdiff_t.
38 *
39 * The type can be considered as a signed version of \c std::size_t. It is needed because
40 * standard type \c 'int' is not specified in respect to its size. E.g. GNU C++ and Clang compiler
41 * use 32-Bit integers for type \c int, even on 64-Bit platforms.
42 *
43 * See also \ref alib::uinteger "alib::uinteger".
44 *
45 * \note This documentation is generated using the 64-Bit version of the library. In fact, the
46 * definition as \c int64_t shown here, is not guaranteed platform specific.
47 *
48 */
49
50using integer = platform_specific;
51
52/**
53 * Unsigned version of \ref alib::integer "alib::integer".
54 * This type should be the same as \c std::size_t on all platforms.
55 */
56using uinteger = platform_specific;
57
58
59/**
60 * This type, together with its counterpart
61 * \ref alib::uintGap_t "alib::uintGap_t" is used to fill a gap that occurs
62 * when method overloads or template specialization are needed for integer types.
63 * The rationale behind and use of this pair of types is best explained with a sample.
64 *
65 * Consider the following code:
66 *
67 * \snippet "DOX_ALIB_ENUMS.cpp" DOX_ALIB_INTXX_DECLARATION
68 *
69 * When this is run under 64 Bit - Linux, GNU compiler, the following output is produced:
70 * \verbinclude "DOX_ALIB_INTXX.txt"
71 *
72 * This is not what many C++ programmers would expect: Although type <c>long long</c> is the same
73 * 64-bit type as <c>long</c>, the template method is not seen as specialized by the compiler.
74 * Therefore, we have a "gap" in the definition of specializations for types
75 * <c>long long</c> and <c>unsigned long long</c>.
76 *
77 * When compiling and running the same sample code under GNU compiler 32-bit or under
78 * MSVC (Microsoft compiler), 32 or 64-bit, then the gap "moves" to be with types
79 * <c>long</c> and <c>unsigned long</c> instead.
80 * Here, this hurts a lot, because code that uses a simple integer constant \c 1L is not fetched by
81 * the template specializations!
82 *
83 * The lesson learned is that two more specializations are needed and that their types are
84 * dependent on the compiler and library used. Because it is not allowed to specialize
85 * simply with all possible extra variants (this would lead to doubly defined methods),
86 * a preprocessor switch that chooses the right types to fill the gap is needed.
87 *
88 * This type, together with #uintGap_t, does exactly this: using the preprocessor to select
89 * the right "missing" type.
90 *
91 * To fix the sample above, the following two specializations of the template method need to
92 * be added:
93 *
94 * \snippet "DOX_ALIB_ENUMS.cpp" DOX_ALIB_INTXX_DECLARATION2
95 *
96 * When overloading functions with integer types, similar rules apply: To have the complete set
97 * of integer types covered, 10 overloads are needed: from type \b int8_t to type \b int64_t,
98 * type \b %intGap_t and then those five types in two versions, signed and unsigned.
99 * Only with all overloads in place, compiler warnings (on high warning levels),
100 * compiler errors due to ambiguouties and/or the necessity of explicit type conversions are
101 * avoided.
102 *
103 * \see
104 * Along with these definitions, preprocessor symbol \ref ALIB_SIZEOF_INTGAP is defined.
105 */
106using intGap_t= platform_specific;
107
108 /**
109 * Used to complete overwriting methods and template specializations.<br>
110 * See signed sibling type \ref alib::intGap_t "alib::intGap_t" for more information.
111 */
112using uintGap_t= platform_specific;
113
114
115
116#else // ALIB_DOX
117
118
119//------------- One of the 5 symbols given from outside? ---------------------
120#if defined(ALIB_SIZEOF_INTEGER ) \
121 || defined(ALIB_SIZEOF_INTGAP ) \
122 || defined(ALIB_INTGAP_TYPE ) \
123 || defined(ALIB_SIZEOF_LONGDOUBLE_REPORTED) \
124 || defined(ALIB_SIZEOF_LONGDOUBLE_WRITTEN)
125
126 // just check if all are given, that's it for now
127 #if !defined(ALIB_SIZEOF_INTEGER) \
128 || !defined(ALIB_SIZEOF_INTGAP) \
129 || !defined(ALIB_INTGAP_TYPE) \
130 || !defined(ALIB_SIZEOF_LONGDOUBLE_REPORTED) \
131 || !defined(ALIB_SIZEOF_LONGDOUBLE_WRITTEN)
132
133 #error "If one of the Compiler Symbols \
134'ALIB_SIZEOF_INTEGER', \
135'ALIB_SIZEOF_INTGAP', \
136'ALIB_INTGAP_TYPE', \
137'ALIB_SIZEOF_LONGDOUBLE_REPORTED' or \
138'ALIB_SIZEOF_LONGDOUBLE_WRITTEN' \
139is given (instead of letting ALib detect them), then the whole group has to be given!"
140 #endif
141
142
143//------------- None of the 5 symbols given from outside: Platform detection ---------------------
144#else
145
146 // 64-Bit platforms
147 #if (defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ == 8 ) || defined(_WIN64)
148
149 #define ALIB_SIZEOF_INTEGER 8
150
151 #if defined(_WIN32)
152 #define ALIB_INTGAP_TYPE long;
153 #define ALIB_SIZEOF_INTGAP 4
154
155 #elif defined(__APPLE__)
156 #define ALIB_INTGAP_TYPE long;
157 #define ALIB_SIZEOF_INTGAP 8
158
159 #elif defined(__GNUC__) || defined(__clang__)
160 #define ALIB_INTGAP_TYPE long long;
161 #define ALIB_SIZEOF_INTGAP 8
162 #else
163 # error "Can not detect compilation platform. Please provide Symbols \
164'ALIB_SIZEOF_INTEGER', \
165'ALIB_SIZEOF_INTGAP', \
166'ALIB_INTGAP_TYPE', \
167'ALIB_SIZEOF_LONGDOUBLE_REPORTED' or \
168'ALIB_SIZEOF_LONGDOUBLE_WRITTEN' \
169as documented with ALib User Manual at https://alib.dev"
170
171 #endif
172
173 #if defined(_MSC_VER) || defined(__APPLE__)
174 # define ALIB_SIZEOF_LONGDOUBLE_REPORTED 8
175 #else
176 # define ALIB_SIZEOF_LONGDOUBLE_REPORTED 16
177 #endif
178
179 // 32-Bit platforms
180 #elif (defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ == 4 ) || defined(_WIN32) || defined( __arm__)
181
182 #define ALIB_SIZEOF_INTEGER 4
183
184 #if defined(__APPLE__)
185 #define ALIB_INTGAP_TYPE long;
186 #define ALIB_SIZEOF_INTGAP 4
187
188 #elif defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER)
189 #define ALIB_INTGAP_TYPE long;
190 #define ALIB_SIZEOF_INTGAP 4
191 #else
192 #error "Can not detect compilation platform. Please provide Symbols \
193'ALIB_SIZEOF_INTEGER', \
194'ALIB_SIZEOF_INTGAP', \
195'ALIB_INTGAP_TYPE', \
196'ALIB_SIZEOF_LONGDOUBLE_REPORTED' or \
197'ALIB_SIZEOF_LONGDOUBLE_WRITTEN' \
198as documented with ALib User Manual at https://alib.dev"
199
200 #endif
201
202 #if defined(_MSC_VER) || defined( __arm__)
203 # define ALIB_SIZEOF_LONGDOUBLE_REPORTED 8
204 #elif defined(__APPLE__)
205 # define ALIB_SIZEOF_LONGDOUBLE_REPORTED 16
206 #else
207 # define ALIB_SIZEOF_LONGDOUBLE_REPORTED 12
208 #endif
209
210 // unrecognized platform
211 #else
212 #error "Can not detect compilation platform. Please provide Symbols \
213'ALIB_SIZEOF_INTEGER', \
214'ALIB_SIZEOF_INTGAP', \
215'ALIB_INTGAP_TYPE', \
216'ALIB_SIZEOF_LONGDOUBLE_REPORTED' or \
217'ALIB_SIZEOF_LONGDOUBLE_WRITTEN' \
218as documented with ALib User Manual at https://alib.dev"
219
220 #endif //64, 32, unrecognized
221
222 // deduct stuff
223 #if (ALIB_SIZEOF_LONGDOUBLE_REPORTED == 8)
224 # define ALIB_SIZEOF_LONGDOUBLE_WRITTEN 8
225 #elif defined(__aarch64__)
226 # define ALIB_SIZEOF_LONGDOUBLE_WRITTEN 16
227 #else
228 # define ALIB_SIZEOF_LONGDOUBLE_WRITTEN 10
229 #endif
230
231
232#endif // No symbol given
233
234// ############# set according to symbols #############
235
236#if ALIB_SIZEOF_INTEGER == 4
237 using integer = int32_t;
238 using uinteger = uint32_t;
239#elif ALIB_SIZEOF_INTEGER == 8
240 using integer = int64_t;
241 using uinteger = uint64_t;
242#else
243 #error "Compiler symbol 'ALIB_SIZEOF_INTEGER' supports only values 4 and 8."
244#endif
245
247using uintGap_t= unsigned ALIB_INTGAP_TYPE;
248
249
250
251// ############# checks #############
252#define ERROR_DETECTING \
253"Can not detect compilation platform. Please provide Symbols \
254'ALIB_SIZEOF_INTEGER', \
255'ALIB_SIZEOF_INTGAP', \
256'ALIB_INTGAP_TYPE', \
257'ALIB_SIZEOF_LONGDOUBLE_REPORTED' or \
258'ALIB_SIZEOF_LONGDOUBLE_WRITTEN' \
259as documented with ALib User Manual at https://alib.dev"
260
261static_assert( sizeof(integer) == sizeof(uinteger ) , "\nSize mismatch in definition of alib::[u]integer on this platform/compiler.\n" ERROR_DETECTING);
262static_assert( sizeof(integer) == sizeof(size_t ) , "\nSize mismatch in definition of alib::[u]integer on this platform/compiler.\n" ERROR_DETECTING);
263static_assert( sizeof(integer) == sizeof(ptrdiff_t) , "\nSize mismatch in definition of alib::[u]integer on this platform/compiler.\n" ERROR_DETECTING);
264static_assert( sizeof(integer) == sizeof(void* ) , "\nSize mismatch in definition of alib::[u]integer on this platform/compiler.\n" ERROR_DETECTING);
265static_assert( sizeof(integer) == ALIB_SIZEOF_INTEGER , "\nSize mismatch in definition of alib::[u]integer on this platform/compiler.\n" ERROR_DETECTING);
266static_assert( sizeof(intGap_t) == ALIB_SIZEOF_INTGAP , "\nDefinition of symbol ALIB_SIZEOF_INTGAP not adjusted to platform/compiler.\n" ERROR_DETECTING);
267static_assert( sizeof(long double) == ALIB_SIZEOF_LONGDOUBLE_REPORTED, "\nSize mismatch in definition of macro ALIB_SIZEOF_LONGDOUBLE_REPORTED on this platform/compiler.\n" ERROR_DETECTING);
268
269
270
271#if !defined(ALIB_SIZEOF_LONGDOUBLE_WRITTEN)
272 #error "Can not detect compilation platform. Please provide Symbols \
273'ALIB_SIZEOF_INTEGER', \
274'ALIB_SIZEOF_INTGAP', \
275'ALIB_INTGAP_TYPE', \
276'ALIB_SIZEOF_LONGDOUBLE_REPORTED' or \
277'ALIB_SIZEOF_LONGDOUBLE_WRITTEN' \
278as documented with ALib User Manual at https://alib.dev"
279#endif
280
281#endif // not ALIB_DOX
282
283} // namespace alib[::lang]
284
285/// Type alias in namespace \b alib.
287
288/// Type alias in namespace \b alib.
290
291/// Type alias in namespace \b alib.
293
294/// Type alias in namespace \b alib.
296
297} // namespace [alib]
298
299#endif // HPP_ALIB_LANG_INTEGERS
#define ALIB_SIZEOF_INTEGER
Definition prepro.dox:26
#define ALIB_SIZEOF_INTGAP
Definition prepro.dox:27
#define ALIB_INTGAP_TYPE
Definition prepro.dox:28
#define ALIB_SIZEOF_LONGDOUBLE_REPORTED
Definition prepro.dox:29
platform_specific intGap_t
Definition integers.hpp:106
platform_specific uintGap_t
Definition integers.hpp:112
platform_specific integer
Definition integers.hpp:50
platform_specific uinteger
Definition integers.hpp:56
Definition alib.cpp:57
lang::uinteger uinteger
Type alias in namespace alib.
Definition integers.hpp:289
lang::intGap_t intGap_t
Type alias in namespace alib.
Definition integers.hpp:292
lang::uintGap_t uintGap_t
Type alias in namespace alib.
Definition integers.hpp:295
lang::integer integer
Type alias in namespace alib.
Definition integers.hpp:286