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