1 /*************************************************************************
3 * Copyright 2016 Realm Inc.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 **************************************************************************/
19 #ifndef REALM_UTIL_FEATURES_H
20 #define REALM_UTIL_FEATURES_H
23 #pragma warning(disable : 4800) // Visual Studio int->bool performance warnings
26 #if defined(_WIN32) && !defined(NOMINMAX)
30 #include <realm/util/config.h>
32 /* The maximum number of elements in a B+-tree node. Applies to inner nodes and
33 * to leaves. The minimum allowable value is 2.
35 #ifndef REALM_MAX_BPNODE_SIZE
36 #define REALM_MAX_BPNODE_SIZE 1000
40 #define REALM_QUOTE_2(x) #x
41 #define REALM_QUOTE(x) REALM_QUOTE_2(x)
43 /* See these links for information about feature check macroes in GCC,
46 * http://gcc.gnu.org/projects/cxx0x.html
47 * http://clang.llvm.org/cxx_status.html
48 * http://clang.llvm.org/docs/LanguageExtensions.html#checks-for-standard-language-features
49 * http://msdn.microsoft.com/en-us/library/vstudio/hh567368.aspx
50 * http://sourceforge.net/p/predef/wiki/Compilers
54 /* Compiler is GCC and version is greater than or equal to the specified version */
55 #define REALM_HAVE_AT_LEAST_GCC(maj, min) \
56 (__GNUC__ > (maj) || __GNUC__ == (maj) && __GNUC_MINOR__ >= (min))
58 #if defined(__clang__)
59 #define REALM_HAVE_CLANG_FEATURE(feature) __has_feature(feature)
60 #define REALM_HAVE_CLANG_WARNING(warning) __has_warning(warning)
62 #define REALM_HAVE_CLANG_FEATURE(feature) 0
63 #define REALM_HAVE_CLANG_WARNING(warning) 0
66 #ifdef __has_cpp_attribute
67 #define REALM_HAS_CPP_ATTRIBUTE(attr) __has_cpp_attribute(attr)
69 #define REALM_HAS_CPP_ATTRIBUTE(attr) 0
72 #if REALM_HAS_CPP_ATTRIBUTE(clang::fallthrough)
73 #define REALM_FALLTHROUGH [[clang::fallthrough]]
74 #elif REALM_HAS_CPP_ATTRIBUTE(fallthrough)
75 #define REALM_FALLTHROUGH [[fallthrough]]
77 #define REALM_FALLTHROUGH
80 // This should be renamed to REALM_UNREACHABLE as soon as REALM_UNREACHABLE is renamed to
81 // REALM_ASSERT_NOT_REACHED which will better reflect its nature
82 #if defined(__GNUC__) || defined(__clang__)
83 #define REALM_COMPILER_HINT_UNREACHABLE __builtin_unreachable
85 #define REALM_COMPILER_HINT_UNREACHABLE abort
88 #if defined(__GNUC__) // clang or GCC
89 #define REALM_PRAGMA(v) _Pragma(REALM_QUOTE_2(v))
90 #elif defined(_MSC_VER) // VS
91 #define REALM_PRAGMA(v) __pragma(v)
93 #define REALM_PRAGMA(v)
96 #if defined(__clang__)
97 #define REALM_DIAG(v) REALM_PRAGMA(clang diagnostic v)
98 #elif defined(__GNUC__)
99 #define REALM_DIAG(v) REALM_PRAGMA(GCC diagnostic v)
101 #define REALM_DIAG(v)
104 #define REALM_DIAG_PUSH() REALM_DIAG(push)
105 #define REALM_DIAG_POP() REALM_DIAG(pop)
108 #define REALM_VS_WARNING_DISABLE #pragma warning (default: 4297)
111 #if REALM_HAVE_CLANG_WARNING("-Wtautological-compare") || REALM_HAVE_AT_LEAST_GCC(6, 0)
112 #define REALM_DIAG_IGNORE_TAUTOLOGICAL_COMPARE() REALM_DIAG(ignored "-Wtautological-compare")
114 #define REALM_DIAG_IGNORE_TAUTOLOGICAL_COMPARE()
118 # define REALM_DIAG_IGNORE_UNSIGNED_MINUS() REALM_PRAGMA(warning(disable:4146))
120 #define REALM_DIAG_IGNORE_UNSIGNED_MINUS()
123 /* Compiler is MSVC (Microsoft Visual C++) */
124 #if defined(_MSC_VER) && _MSC_VER >= 1600
125 #define REALM_HAVE_AT_LEAST_MSVC_10_2010 1
127 #if defined(_MSC_VER) && _MSC_VER >= 1700
128 #define REALM_HAVE_AT_LEAST_MSVC_11_2012 1
130 #if defined(_MSC_VER) && _MSC_VER >= 1800
131 #define REALM_HAVE_AT_LEAST_MSVC_12_2013 1
135 /* The way to specify that a function never returns. */
136 #if REALM_HAVE_AT_LEAST_GCC(4, 8) || REALM_HAVE_CLANG_FEATURE(cxx_attributes)
137 #define REALM_NORETURN [[noreturn]]
139 #define REALM_NORETURN __attribute__((noreturn))
140 #elif defined(_MSC_VER)
141 #define REALM_NORETURN __declspec(noreturn)
143 #define REALM_NORETURN
147 /* The way to specify that a variable or type is intended to possibly
148 * not be used. Use it to suppress a warning from the compiler. */
150 #define REALM_UNUSED __attribute__((unused))
155 /* The way to specify that a function is deprecated
156 * not be used. Use it to suppress a warning from the compiler. */
158 #define REALM_DEPRECATED(x) [[deprecated(x)]]
160 #define REALM_DEPRECATED(x) __declspec(deprecated(x))
164 #if __GNUC__ || defined __INTEL_COMPILER
165 #define REALM_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
166 #define REALM_LIKELY(expr) __builtin_expect(!!(expr), 1)
168 #define REALM_UNLIKELY(expr) (expr)
169 #define REALM_LIKELY(expr) (expr)
173 #if defined(__GNUC__) || defined(__HP_aCC)
174 #define REALM_FORCEINLINE inline __attribute__((always_inline))
175 #elif defined(_MSC_VER)
176 #define REALM_FORCEINLINE __forceinline
178 #define REALM_FORCEINLINE inline
182 #if defined(__GNUC__) || defined(__HP_aCC)
183 #define REALM_NOINLINE __attribute__((noinline))
184 #elif defined(_MSC_VER)
185 #define REALM_NOINLINE __declspec(noinline)
187 #define REALM_NOINLINE
191 /* Thread specific data (only for POD types) */
192 #if defined __clang__
193 #define REALM_THREAD_LOCAL __thread
195 #define REALM_THREAD_LOCAL thread_local
200 #define REALM_ANDROID 1
202 #define REALM_ANDROID 0
206 # include <winapifamily.h>
207 # if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM)
208 # define REALM_WINDOWS 1
210 # elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
211 # define REALM_WINDOWS 0
215 #define REALM_WINDOWS 0
219 // Some documentation of the defines provided by Apple:
220 // http://developer.apple.com/library/mac/documentation/Porting/Conceptual/PortingUnix/compiling/compiling.html#//apple_ref/doc/uid/TP40002850-SW13
221 #if defined __APPLE__ && defined __MACH__
222 #define REALM_PLATFORM_APPLE 1
223 /* Apple OSX and iOS (Darwin). */
224 #include <Availability.h>
225 #include <TargetConditionals.h>
226 #if TARGET_OS_IPHONE == 1
227 /* Device (iPhone or iPad) or simulator. */
232 #if TARGET_OS_WATCH == 1
233 /* Device (Apple Watch) or simulator. */
234 #define REALM_WATCHOS 1
236 #define REALM_WATCHOS 0
239 /* Device (Apple TV) or simulator. */
245 #define REALM_PLATFORM_APPLE 0
247 #define REALM_WATCHOS 0
251 // asl_log is deprecated in favor of os_log as of the following versions:
252 // macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)
253 // versions are defined in /usr/include/Availability.h
254 // __MAC_10_12 101200
255 // __IPHONE_10_0 100000
256 // __WATCHOS_3_0 30000
257 // __TVOS_10_0 100000
258 #if REALM_PLATFORM_APPLE \
260 (REALM_IOS && defined(__IPHONE_OS_VERSION_MIN_REQUIRED) \
261 && __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000) \
262 || (REALM_TVOS && defined(__TV_OS_VERSION_MIN_REQUIRED) \
263 && __TV_OS_VERSION_MIN_REQUIRED >= 100000) \
264 || (REALM_WATCHOS && defined(__WATCH_OS_VERSION_MIN_REQUIRED) \
265 && __WATCH_OS_VERSION_MIN_REQUIRED >= 30000) \
266 || (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) \
267 && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200) \
269 #define REALM_APPLE_OS_LOG 1
271 #define REALM_APPLE_OS_LOG 0
274 #if REALM_ANDROID || REALM_IOS || REALM_WATCHOS || REALM_TVOS || REALM_UWP
275 #define REALM_MOBILE 1
277 #define REALM_MOBILE 0
281 #if defined(REALM_DEBUG) && !defined(REALM_COOKIE_CHECK)
282 #define REALM_COOKIE_CHECK
285 #if !REALM_IOS && !REALM_WATCHOS && !REALM_TVOS && !defined(_WIN32) && !REALM_ANDROID
286 #define REALM_ASYNC_DAEMON
289 // We're in i686 mode
290 #if defined(__i386) || defined(__i386__) || defined(__i686__) || defined(_M_I86) || defined(_M_IX86)
291 #define REALM_ARCHITECTURE_X86_32 1
293 #define REALM_ARCHITECTURE_X86_32 0
296 // We're in amd64 mode
297 #if defined(__amd64) || defined(__amd64__) || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
299 #define REALM_ARCHITECTURE_X86_64 1
301 #define REALM_ARCHITECTURE_X86_64 0
304 #endif /* REALM_UTIL_FEATURES_H */