Couchbase Lite C
Couchbase Lite C API
vendor
couchbase-lite-core
vendor
fleece
API
fleece
Base.h
Go to the documentation of this file.
1
//
2
// Base.h
3
//
4
// Copyright 2018-Present Couchbase, Inc.
5
//
6
// Use of this software is governed by the Business Source License included
7
// in the file licenses/BSL-Couchbase.txt. As of the Change Date specified
8
// in that file, in accordance with the Business Source License, use of this
9
// software will be governed by the Apache License, Version 2.0, included in
10
// the file licenses/APL2.txt.
11
//
12
13
#pragma once
14
#ifndef FLEECE_BASE_H
15
#define FLEECE_BASE_H
16
17
// The __has_xxx() macros are only(?) implemented by Clang. (Except GCC has __has_attribute...)
18
// Define them to return 0 on other compilers.
19
// https://clang.llvm.org/docs/AttributeReference.html
20
// https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
21
22
#ifndef __has_attribute
23
#define __has_attribute(x) 0
24
#endif
25
26
#ifndef __has_builtin
27
#define __has_builtin(x) 0
28
#endif
29
30
#ifndef __has_feature
31
#define __has_feature(x) 0
32
#endif
33
34
#ifndef __has_extension
35
#define __has_extension(x) 0
36
#endif
37
38
39
#if defined(__clang__) || defined(__GNUC__)
40
// Tells the optimizer that a function's return value is never NULL.
41
#define RETURNS_NONNULL __attribute__((returns_nonnull))
42
43
// Triggers a compile error if a call to the function ignores the returned value.
44
// Typically this is because the return value is something that must be released/freed.
45
#define MUST_USE_RESULT __attribute__((warn_unused_result))
46
47
// These have no effect on behavior, but they hint to the optimizer which branch of an 'if'
48
// statement to make faster.
49
#define _usuallyTrue(VAL) __builtin_expect(VAL, true)
50
#define _usuallyFalse(VAL) __builtin_expect(VAL, false)
51
#else
52
#define RETURNS_NONNULL
53
#define MUST_USE_RESULT
54
55
#define _usuallyTrue(VAL) (VAL)
56
#define _usuallyFalse(VAL) (VAL)
57
#endif
58
59
60
// Declares that a parameter must not be NULL. The compiler can sometimes detect violations
61
// of this at compile time, if the parameter value is a literal.
62
// The Clang Undefined-Behavior Sanitizer will detect all violations at runtime.
63
// GCC also has an attribute with this name, but it's incompatible: it can't be applied to a
64
// parameter, it has to come after the function and list parameters by number. Oh well.
65
#ifdef __clang__
66
#define NONNULL __attribute__((nonnull))
67
#else
68
#define NONNULL
69
#endif
70
71
72
// FLPURE functions are _read-only_. They cannot write to memory (in a way that's detectable),
73
// and they cannot access volatile data or do I/O.
74
//
75
// Calling an FLPURE function twice in a row with the same arguments must return the same result.
76
//
77
// "Many functions have no effects except the return value, and their return value depends only on
78
// the parameters and/or global variables. Such a function can be subject to common subexpression
79
// elimination and loop optimization just as an arithmetic operator would be. These functions
80
// should be declared with the attribute pure."
81
// "The pure attribute prohibits a function from modifying the state of the program that is
82
// observable by means other than inspecting the function’s return value. However, functions
83
// declared with the pure attribute can safely read any non-volatile objects, and modify the value
84
// of objects in a way that does not affect their return value or the observable state of the
85
// program." -- GCC manual
86
#if defined(__GNUC__) || __has_attribute(__pure__)
87
#define FLPURE __attribute__((__pure__))
88
#else
89
#define FLPURE
90
#endif
91
92
// FLCONST is even stricter than FLPURE. The function cannot access memory at all (except for
93
// reading immutable values like constants.) The return value can only depend on the parameters.
94
//
95
// Calling an FLCONST function with the same arguments must _always_ return the same result.
96
//
97
// "Calls to functions whose return value is not affected by changes to the observable state of the
98
// program and that have no observable effects on such state other than to return a value may lend
99
// themselves to optimizations such as common subexpression elimination. Declaring such functions
100
// with the const attribute allows GCC to avoid emitting some calls in repeated invocations of the
101
// function with the same argument values."
102
// "Note that a function that has pointer arguments and examines the data pointed to must not be
103
// declared const if the pointed-to data might change between successive invocations of the
104
// function.
105
// "In general, since a function cannot distinguish data that might change from data that cannot,
106
// const functions should never take pointer or, in C++, reference arguments. Likewise, a function
107
// that calls a non-const function usually must not be const itself." -- GCC manual
108
#if defined(__GNUC__) || __has_attribute(__const__)
109
#define FLCONST __attribute__((__const__))
110
#else
111
#define FLCONST
112
#endif
113
114
115
// `constexpr14` is for uses of `constexpr` that are valid in C++14 but not earlier.
116
// In constexpr functions this includes `if`, `for`, `while` statements; or multiple `return`s.
117
// The macro expands to `constexpr` in C++14 or later, otherwise to nothing.
118
#ifdef __cplusplus
119
#if __cplusplus >= 201400L || _MSVC_LANG >= 201400L
120
#define constexpr14 constexpr
121
#else
122
#define constexpr14
123
#endif
124
#endif
// __cplusplus
125
126
127
// STEPOVER is for trivial little glue functions that are annoying to step into in the debugger
128
// on the way to the function you _do_ want to step into. Examples are RefCounted's operator->,
129
// or slice constructors. Suppressing debug info for those functions means the debugger
130
// will continue through them when stepping in.
131
// (It probably also makes the debug-symbol file smaller.)
132
#if __has_attribute(nodebug)
133
#define STEPOVER __attribute((nodebug))
134
#else
135
#define STEPOVER
136
#endif
137
138
139
// Note: Code below adapted from libmdbx source code.
140
141
// `__optimize` is used by the macros below -- you should probably not use it directly, instead
142
// use `__hot` or `__cold`. It applies a specific compiler optimization level to a function,
143
// e.g. __optimize("O3") or __optimize("Os"). Has no effect in an unoptimized build.
144
#ifndef __optimize
145
# if defined(__OPTIMIZE__)
146
# if defined(__clang__) && !__has_attribute(__optimize__)
147
# define __optimize(ops)
148
# elif defined(__GNUC__) || __has_attribute(__optimize__)
149
# define __optimize(ops) __attribute__((__optimize__(ops)))
150
# else
151
# define __optimize(ops)
152
# endif
153
# else
154
# define __optimize(ops)
155
# endif
156
#endif
/* __optimize */
157
158
#if defined(__clang__)
159
#define HOTLEVEL "Ofast"
160
#define COLDLEVEL "Oz"
161
#else
162
#define HOTLEVEL "O3"
163
#define COLDLEVEL "Os"
164
#endif
165
166
// `__hot` marks a function as being a hot-spot. Optimizes it for speed and may move it to a common
167
// code section for hot functions. Has no effect in an unoptimized build.
168
#ifndef __hot
169
# if defined(__OPTIMIZE__)
170
# if defined(__clang__) && !__has_attribute(__hot__) \
171
&& __has_attribute(__section__) && (defined(__linux__) || defined(__gnu_linux__))
172
/* just put frequently used functions in separate section */
173
# define __hot __attribute__((__section__("text.hot"
))) __optimize(HOTLEVEL)
174
# elif defined(__GNUC__) || __has_attribute(__hot__)
175
# define __hot __attribute__((__hot__)) __optimize(HOTLEVEL)
176
# else
177
# define __hot __optimize(HOTLEVEL)
178
# endif
179
# else
180
# define __hot
181
# endif
182
#endif
/* __hot */
183
184
// `__cold` marks a function as being rarely used (e.g. error handling.) Optimizes it for size and
185
// moves it to a common code section for cold functions. Has no effect in an unoptimized build.
186
#ifndef __cold
187
# if defined(__OPTIMIZE__)
188
# if defined(__clang__) && !__has_attribute(__cold__) \
189
&& __has_attribute(__section__) && (defined(__linux__) || defined(__gnu_linux__))
190
/* just put infrequently used functions in separate section */
191
# define __cold __attribute__((__section__("text.unlikely"
))) __optimize(COLDLEVEL)
192
# elif defined(__GNUC__) || __has_attribute(__cold__)
193
# define __cold __attribute__((__cold__)) __optimize(COLDLEVEL)
194
# else
195
# define __cold __optimize(COLDLEVEL)
196
# endif
197
# else
198
# define __cold
199
# endif
200
#endif
/* __cold */
201
202
203
#ifndef _MSC_VER
204
#define WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) 0
205
#endif
206
207
208
#else
// FLEECE_BASE_H
209
#warn "Compiler is not honoring #pragma once"
210
#endif
Generated by
1.9.2