libcopp  2.2.0
features.h
Go to the documentation of this file.
1 // cmake template file
2 
3 #ifndef COPP_UTILS_FEATURES_H
4 #define COPP_UTILS_FEATURES_H
5 
6 #pragma once
7 
8 // ================ build options ================
9 #include <libcopp/utils/config/libcopp_build_features.h>
10 // ---------------- build options ----------------
11 
12 // ================ select compiler ================
13 #if defined(__GCCXML__)
14 # define COPP_MACRO_COMPILER_GCCXML 1
15 #elif defined(__clang__)
16 # define COPP_MACRO_COMPILER_CLANG 1
17 #elif defined(_MSC_VER)
18 # define COPP_MACRO_COMPILER_MSVC 1
19 #elif defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC)
20 # define COPP_MACRO_COMPILER_INTELC 1
21 #elif defined(__GNUC__)
22 # define COPP_MACRO_COMPILER_GCC 1
23 #elif defined(__BORLANDC__)
24 # define COPP_MACRO_COMPILER_BORLANDC 1
25 #endif
26 // ---------------- select compiler ----------------
27 
28 // ================ select platform ================
29 #if (defined(linux) || defined(__linux) || defined(__linux__) || defined(__GNU__) || defined(__GLIBC__)) && \
30  !defined(_CRAYC)
31 # define COPP_MACRO_PLATFORM_LINUX
32 #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
33 # define COPP_MACRO_PLATFORM_BSD
34 #elif defined(sun) || defined(__sun)
35 # define COPP_MACRO_PLATFORM_SOLARIS
36 #elif defined(__sgi)
37 # define COPP_MACRO_PLATFORM_SGI
38 #elif defined(__hpux)
39 # define COPP_MACRO_PLATFORM_HPUNIX
40 #elif defined(__CYGWIN__)
41 # define COPP_MACRO_PLATFORM_CYGWIN
42 #elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
43 # define COPP_MACRO_PLATFORM_WIN32
44 #else
45 # if defined(unix) || defined(__unix) || defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE)
46 # define COPP_MACRO_PLATFORM_UNIX
47 # endif
48 #endif
49 // ---------------- select platform ----------------
50 
51 // ---------------- c extern ----------------
52 
53 // ================ compiler abi headers ================
54 #if defined(COPP_MACRO_COMPILER_MSVC)
55 # define COPP_HAS_ABI_HEADERS 1
56 # define COPP_ABI_PREFIX "libcopp/utils/abi/msvc_prefix.hpp"
57 # define COPP_ABI_SUFFIX "libcopp/utils/abi/msvc_suffix.hpp"
58 #elif defined COPP_MACRO_COMPILER_BORLANDC
59 # define COPP_HAS_ABI_HEADERS 1
60 # define COPP_ABI_PREFIX "libcopp/utils/abi/borland_prefix.hpp"
61 # define COPP_ABI_SUFFIX "libcopp/utils/abi/borland_suffix.hpp"
62 #endif
63 // ---------------- compiler abi headers ----------------
64 
65 // ================ function flags ================
66 
67 #if defined(LIBCOPP_MACRO_USE_SEGMENTED_STACKS)
68 # if !((defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ > 3 && __GNUC_MINOR__ > 6))) || \
69  (defined(__clang__) && __clang_major__ > 2 && __clang_minor__ > 3))
70 # error "compiler does not support segmented_stack stacks"
71 # endif
72 # define COPP_MACRO_SEGMENTED_STACK_NUMBER 10
73 #endif
74 
75 #ifndef COPP_MACRO_CPP_STD
76 # if defined(__cplusplus) && __cplusplus >= 201103L
77 # define COPP_MACRO_CPP_STD 201103L
78 # define COPP_MACRO_ENABLE_SMART_PTR 1
79 # else
80 # define COPP_MACRO_CPP_STD 199711L
81 # endif
82 #endif
83 
84 #if defined(_POSIX_MT_) || defined(_MSC_VER)
85 # define COPP_MACRO_ENABLE_MULTI_THREAD
86 #endif
87 // ---------------- function flags ----------------
88 
89 // ================ branch prediction information ================
90 #if !defined(COPP_LIKELY_IF) && defined(__cplusplus)
91 // GCC 9 has likely attribute but do not support declare it at the beginning of statement
92 # if defined(__has_cpp_attribute) && (defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 9)
93 # if __has_cpp_attribute(likely)
94 # define COPP_LIKELY_IF(...) if (__VA_ARGS__) [[likely]]
95 # endif
96 # endif
97 #endif
98 #if !defined(COPP_LIKELY_IF) && (defined(__clang__) || defined(__GNUC__))
99 # define COPP_LIKELY_IF(...) if (__builtin_expect(!!(__VA_ARGS__), true))
100 #endif
101 #ifndef COPP_LIKELY_IF
102 # define COPP_LIKELY_IF(...) if (__VA_ARGS__)
103 #endif
104 
105 #if !defined(COPP_UNLIKELY_IF) && defined(__cplusplus)
106 // GCC 9 has likely attribute but do not support declare it at the beginning of statement
107 # if defined(__has_cpp_attribute) && (defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 9)
108 # if __has_cpp_attribute(likely)
109 # define COPP_UNLIKELY_IF(...) if (__VA_ARGS__) [[unlikely]]
110 # endif
111 # endif
112 #endif
113 #if !defined(COPP_UNLIKELY_IF) && (defined(__clang__) || defined(__GNUC__))
114 # define COPP_UNLIKELY_IF(...) if (__builtin_expect(!!(__VA_ARGS__), false))
115 #endif
116 #ifndef COPP_UNLIKELY_IF
117 # define COPP_UNLIKELY_IF(...) if (__VA_ARGS__)
118 #endif
119 
120 // ---------------- branch prediction information ----------------
121 
122 #if !defined(COPP_NORETURN_ATTR) && defined(__has_cpp_attribute)
123 # if __has_cpp_attribute(noreturn)
124 # define COPP_NORETURN_ATTR [[noreturn]]
125 # endif
126 #endif
127 #ifndef COPP_NORETURN_ATTR
128 # define COPP_NORETURN_ATTR
129 #endif
130 
131 #ifndef COPP_UNREACHABLE
132 # if defined(__cpp_lib_unreachable)
133 # if __cpp_lib_unreachable
134 # define COPP_UNREACHABLE() std::unreachable()
135 # endif
136 # endif
137 # if !defined(COPP_UNREACHABLE) && defined(unreachable)
138 # define COPP_UNREACHABLE() unreachable()
139 # endif
140 # if !defined(COPP_UNREACHABLE)
141 # ifdef __GNUC__
142 # ifdef __clang__
143 # if __has_builtin(__builtin_unreachable)
144 # define COPP_UNREACHABLE() __builtin_unreachable()
145 # endif
146 # else
147 # if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
148 # define COPP_UNREACHABLE() __builtin_unreachable()
149 # endif
150 # endif
151 # endif
152 # endif
153 #endif
154 #if !defined(COPP_UNREACHABLE)
155 # if defined(_DEBUG) || !defined(NDEBUG)
156 # define COPP_UNREACHABLE() std::abort()
157 # else
158 # define COPP_UNREACHABLE()
159 # endif
160 #endif
161 
162 #include "errno.h"
163 
164 #if !defined(COPP_MACRO_RV_REF)
165 # define COPP_MACRO_RV_REF &&
166 #endif
167 
168 #if !defined(COPP_MACRO_STD_MOVE)
169 # define COPP_MACRO_STD_MOVE(x) std::move(x)
170 #endif
171 
172 #if !defined(COPP_MACRO_STD_FORWARD)
173 # define COPP_MACRO_STD_FORWARD(t, x) std::forward<t>(x)
174 #endif
175 
176 // ================ branch prediction information ================
177 #if defined(COPP_MACRO_COMPILER_GCC)
178 # if (__GNUC__ * 100 + __GNUC_MINOR__) >= 408 && __cplusplus >= 201103L
179 # define COPP_MACRO_COMPILER_CXX_THREAD_LOCAL 1
180 # else
181 # define COPP_MACRO_COMPILER_CXX_THREAD_LOCAL 0
182 # endif
183 #elif defined(COPP_MACRO_COMPILER_CLANG)
184 # if __has_feature(cxx_thread_local)
185 # define COPP_MACRO_COMPILER_CXX_THREAD_LOCAL 1
186 # else
187 # define COPP_MACRO_COMPILER_CXX_THREAD_LOCAL 0
188 # endif
189 #elif defined(_MSC_VER)
190 # if _MSC_VER >= 1900
191 # define COPP_MACRO_COMPILER_CXX_THREAD_LOCAL 1
192 # else
193 # define COPP_MACRO_COMPILER_CXX_THREAD_LOCAL 0
194 # endif
195 #endif
196 
197 // iOS may not link STL with thread_local
198 #if defined(__APPLE__)
199 # include <TargetConditionals.h>
200 
201 # if TARGET_OS_IPHONE || TARGET_OS_EMBEDDED || TARGET_IPHONE_SIMULATOR
202 # define COPP_MACRO_DISABLE_THREAD_LOCAL_KEYWORK
203 # endif
204 #endif
205 
206 // android may not link STL with thread_local
207 #if defined(__ANDROID__)
208 # define COPP_MACRO_DISABLE_THREAD_LOCAL_KEYWORK
209 #endif
210 
211 #if !defined(COPP_MACRO_DISABLE_THREAD_LOCAL_KEYWORK)
212 # if defined(COPP_MACRO_COMPILER_CXX_THREAD_LOCAL) && COPP_MACRO_COMPILER_CXX_THREAD_LOCAL
213 # define COPP_MACRO_THREAD_LOCAL thread_local
214 # elif defined(COPP_MACRO_COMPILER_GCC) || defined(COPP_MACRO_COMPILER_CLANG)
215 # define COPP_MACRO_THREAD_LOCAL __thread
216 # elif defined(_MSC_VER)
217 # define COPP_MACRO_THREAD_LOCAL __declspec(thread)
218 # else
219 // COPP_MACRO_THREAD_LOCAL not defined for this configuration.
220 # endif
221 #endif
222 // ---------------- branch prediction information ----------------
223 
224 #endif