aboutsummaryrefslogtreecommitdiffstats
path: root/util/system/defaults.h
blob: dcd7abea38e4d1a520478dfc54b313f66b0835cd (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#pragma once

#include "platform.h"

#if defined _unix_
    #define LOCSLASH_C '/'
    #define LOCSLASH_S "/"
#else
    #define LOCSLASH_C '\\'
    #define LOCSLASH_S "\\"
#endif // _unix_

#if defined(__INTEL_COMPILER) && defined(__cplusplus)
    #include <new>
#endif

// low and high parts of integers
#if !defined(_win_)
    #include <sys/param.h>
#endif

#if defined(BSD) || defined(_android_)

    #if defined(BSD)
        #include <machine/endian.h>
    #endif

    #if defined(_android_)
        #include <endian.h>
    #endif

    #if (BYTE_ORDER == LITTLE_ENDIAN)
        #define _little_endian_
    #elif (BYTE_ORDER == BIG_ENDIAN)
        #define _big_endian_
    #else
        #error unknown endian not supported
    #endif

#elif (defined(_sun_) && !defined(__i386__)) || defined(_hpux_) || defined(WHATEVER_THAT_HAS_BIG_ENDIAN)
    #define _big_endian_
#else
    #define _little_endian_
#endif

// alignment
#if (defined(_sun_) && !defined(__i386__)) || defined(_hpux_) || defined(__alpha__) || defined(__ia64__) || defined(WHATEVER_THAT_NEEDS_ALIGNING_QUADS)
    #define _must_align8_
#endif

#if (defined(_sun_) && !defined(__i386__)) || defined(_hpux_) || defined(__alpha__) || defined(__ia64__) || defined(WHATEVER_THAT_NEEDS_ALIGNING_LONGS)
    #define _must_align4_
#endif

#if (defined(_sun_) && !defined(__i386__)) || defined(_hpux_) || defined(__alpha__) || defined(__ia64__) || defined(WHATEVER_THAT_NEEDS_ALIGNING_SHORTS)
    #define _must_align2_
#endif

#if defined(__GNUC__)
    #define alias_hack __attribute__((__may_alias__))
#endif

#ifndef alias_hack
    #define alias_hack
#endif

#include "types.h"

#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
    #define PRAGMA(x) _Pragma(#x)
    #define RCSID(idstr) PRAGMA(comment(exestr, idstr))
#else
    #define RCSID(idstr) static const char rcsid[] = idstr
#endif

#include "compiler.h"

#ifdef _win_
    #include <malloc.h>
#elif defined(_sun_)
    #include <alloca.h>
#endif

#ifdef NDEBUG
    #define Y_IF_DEBUG(X)
    #ifdef __cplusplus
constexpr bool Y_IS_DEBUG_BUILD = false;
    #endif
#else
    #define Y_IF_DEBUG(X) X
    #ifdef __cplusplus
constexpr bool Y_IS_DEBUG_BUILD = true;
    #endif
#endif

/**
 * @def Y_ARRAY_SIZE
 *
 * This macro is needed to get number of elements in a statically allocated fixed size array. The
 * expression is a compile-time constant and therefore can be used in compile time computations.
 *
 * @code
 * enum ENumbers {
 *     EN_ONE,
 *     EN_TWO,
 *     EN_SIZE
 * }
 *
 * const char* NAMES[] = {
 *     "one",
 *     "two"
 * }
 *
 * static_assert(Y_ARRAY_SIZE(NAMES) == EN_SIZE, "you should define `NAME` for each enumeration");
 * @endcode
 *
 * This macro also catches type errors. If you see a compiler error like "warning: division by zero
 * is undefined" when using `Y_ARRAY_SIZE` then you are probably giving it a pointer.
 *
 * Since all of our code is expected to work on a 64 bit platform where pointers are 8 bytes we may
 * falsefully accept pointers to types of sizes that are divisors of 8 (1, 2, 4 and 8).
 */
#if defined(__cplusplus)
    #include <util/generic/array_size.h>
#else
    #undef Y_ARRAY_SIZE
    #define Y_ARRAY_SIZE(arr) \
        ((sizeof(arr) / sizeof((arr)[0])) / static_cast<size_t>(!(sizeof(arr) % sizeof((arr)[0]))))
#endif

#undef Y_ARRAY_BEGIN
#define Y_ARRAY_BEGIN(arr) (arr)

#undef Y_ARRAY_END
#define Y_ARRAY_END(arr) ((arr) + Y_ARRAY_SIZE(arr))

/**
 * Concatenates two symbols, even if one of them is itself a macro.
 */
#define Y_CAT(X, Y) Y_CAT_I(X, Y)
#define Y_CAT_I(X, Y) Y_CAT_II(X, Y)
#define Y_CAT_II(X, Y) X##Y

#define Y_STRINGIZE(X) UTIL_PRIVATE_STRINGIZE_AUX(X)
#define UTIL_PRIVATE_STRINGIZE_AUX(X) #X

#if defined(__COUNTER__)
    #define Y_GENERATE_UNIQUE_ID(N) Y_CAT(N, __COUNTER__)
#endif

#if !defined(Y_GENERATE_UNIQUE_ID)
    #define Y_GENERATE_UNIQUE_ID(N) Y_CAT(N, __LINE__)
#endif

#define NPOS ((size_t)-1)