plugify 1.2.6
Loading...
Searching...
No Matches
macro.hpp
1#pragma once
2
3#ifndef __has_cpp_attribute
4# define __has_cpp_attribute(x) 0
5#endif
6#ifndef __has_extension
7# define __has_extension(x) 0
8#endif
9#ifndef __has_feature
10# define __has_feature(x) 0
11#endif
12#ifndef __has_include
13# define __has_include(x) 0
14#endif
15#ifndef __has_builtin
16# define __has_builtin(x) 0
17#endif
18
19#define PLUGIFY_HAS_EXCEPTIONS (__cpp_exceptions || __EXCEPTIONS || _HAS_EXCEPTIONS)
20
21#ifndef PLUGIFY_EXCEPTIONS
22# if PLUGIFY_HAS_EXCEPTIONS
23# define PLUGIFY_EXCEPTIONS 1
24# else
25# define PLUGIFY_EXCEPTIONS 0
26# endif
27#endif
28
29#if PLUGIFY_EXCEPTIONS && (!PLUGIFY_HAS_EXCEPTIONS || !__has_include(<stdexcept>))
30# undef PLUGIFY_EXCEPTIONS
31# define PLUGIFY_EXCEPTIONS 0
32#endif
33
34#ifndef PLUGIFY_FALLBACK_ASSERT
35# define PLUGIFY_FALLBACK_ASSERT 1
36#endif
37
38#if PLUGIFY_FALLBACK_ASSERT && !__has_include(<cassert>)
39# undef PLUGIFY_FALLBACK_ASSERT
40# define PLUGIFY_FALLBACK_ASSERT 0
41#endif
42
43#ifndef PLUGIFY_FALLBACK_ABORT
44# define PLUGIFY_FALLBACK_ABORT 1
45#endif
46
47#if PLUGIFY_FALLBACK_ABORT && !__has_include(<cstdlib>)
48# undef PLUGIFY_FALLBACK_ABORT
49# define PLUGIFY_FALLBACK_ABORT 0
50#endif
51
52#ifndef PLUGIFY_FALLBACK_ABORT_FUNCTION
53# define PLUGIFY_FALLBACK_ABORT_FUNCTION [] (auto) { }
54#endif
55
56#if PLUGIFY_EXCEPTIONS
57# include <stdexcept>
58# include <type_traits>
59# define PLUGIFY_ASSERT(x, str, e) do { if (!(x)) [[unlikely]] plugify_throw<e>(str); } while (0)
60#elif PLUGIFY_FALLBACK_ASSERT
61# include <cassert>
62# define PLUGIFY_ASSERT(x, str, ...) assert((x) && (str))
63#elif PLUGIFY_FALLBACK_ABORT
64# include <cstdlib>
65# define PLUGIFY_ASSERT(x, ...) do { if (!(x)) [[unlikely]] { std::abort(); } } while (0)
66#else
67# define PLUGIFY_ASSERT(x, str, ...) do { if (!(x)) [[unlikely]] { PLUGIFY_FALLBACK_ABORT_FUNCTION (str); { while (true) { [] { } (); } } } } while (0)
68#endif
69
70# define PLUGIFY_COMPILER_MAKE_VERSION2(version, sp) ((version) * 100 + (sp))
71# define PLUGIFY_COMPILER_MAKE_VERSION3(major, minor, patch) ((major) * 10000 + (minor) * 100 + (patch))
72
73#if defined(__clang__)
74
75# ifndef PLUGIFY_COMPILER_CLANG
76# define PLUGIFY_COMPILER_CLANG 1
77# endif
78
79# define PLUGIFY_COMPILER_CLANG_VERSION PLUGIFY_COMPILER_MAKE_VERSION3(__clang_major__, __clang_minor__, __clang_patchlevel__)
80# define PLUGIFY_CLANG_AT_LEAST(major, minor, patch) (PLUGIFY_COMPILER_CLANG_VERSION >= PLUGIFY_COMPILER_MAKE_VERSION3((major), (minor), (patch)))
81# define PLUGIFY_CLANG_BEFORE(major, minor, patch) (PLUGIFY_COMPILER_CLANG_VERSION < PLUGIFY_COMPILER_MAKE_VERSION3((major), (minor), (patch)))
82
83#if PLUGIFY_CLANG_BEFORE(15, 0, 0)
84# error "clang version 15 required"
85#endif
86
87#elif defined(__GNUC__)
88
89# ifndef PLUGIFY_COMPILER_GCC
90# define PLUGIFY_COMPILER_GCC 1
91# endif
92
93# define PLUGIFY_COMPILER_GCC_VERSION PLUGIFY_COMPILER_MAKE_VERSION3(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
94# define PLUGIFY_GCC_AT_LEAST(major, minor, patch) (PLUGIFY_COMPILER_GCC_VERSION >= PLUGIFY_COMPILER_MAKE_VERSION3((major), (minor), (patch)))
95# define PLUGIFY_GCC_BEFORE(major, minor, patch) (PLUGIFY_COMPILER_GCC_VERSION < PLUGIFY_COMPILER_MAKE_VERSION3((major), (minor), (patch)))
96
97#if PLUGIFY_GCC_BEFORE(11, 1, 0)
98# error "GCC version 11.1 required"
99#endif
100
101#elif defined(_MSC_VER)
102
103# ifndef PLUGIFY_COMPILER_MSVC
104# define PLUGIFY_COMPILER_MSVC 1
105# endif
106
107#if (_MSC_VER >= 1943)
108# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2022, 13)
109#elif (_MSC_VER >= 1942)
110# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2022, 12)
111#elif (_MSC_VER >= 1941)
112# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2022, 11)
113#elif (_MSC_VER >= 1940)
114# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2022, 10)
115#elif (_MSC_VER >= 1939)
116# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2022, 9)
117#elif (_MSC_VER >= 1938)
118# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2022, 8)
119#elif (_MSC_VER >= 1937)
120# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2022, 7)
121#elif (_MSC_VER >= 1936)
122# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2022, 6)
123#elif (_MSC_VER >= 1935)
124# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2022, 5)
125#elif (_MSC_VER >= 1934)
126# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2022, 4)
127#elif (_MSC_VER >= 1933)
128# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2022, 3)
129#elif (_MSC_VER >= 1932)
130# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2022, 2)
131#elif (_MSC_VER >= 1931)
132# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2022, 1)
133#elif (_MSC_VER >= 1930)
134# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2022, 0)
135#elif (_MSC_VER >= 1929)
136# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2019, 10)
137#elif (_MSC_VER >= 1928)
138# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2019, 8)
139#elif (_MSC_VER >= 1927)
140# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2019, 7)
141#elif (_MSC_VER >= 1926)
142# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2019, 6)
143#elif (_MSC_VER >= 1925)
144# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2019, 5)
145#elif (_MSC_VER >= 1924)
146# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2019, 4)
147#elif (_MSC_VER >= 1923)
148# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2019, 3)
149#elif (_MSC_VER >= 1922)
150# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2019, 2)
151#elif (_MSC_VER >= 1921)
152# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2019, 1)
153#elif (_MSC_VER >= 1920)
154# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2019, 0)
155#elif (_MSC_VER >= 1916)
156# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2017, 9)
157#elif (_MSC_VER >= 1915)
158# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2017, 8)
159#elif (_MSC_VER >= 1914)
160# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2017, 7)
161#elif (_MSC_VER >= 1913)
162# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2017, 6)
163#elif (_MSC_VER >= 1912)
164# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2017, 5)
165#elif (_MSC_VER >= 1911)
166# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2017, 3)
167#elif (_MSC_VER >= 1910)
168# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2017, 0)
169#elif (_MSC_VER >= 1900) && defined(_MSVC_LANG)
170# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2015, 3)
171#elif (_MSC_VER >= 1900)
172# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2015, 0)
173#elif (_MSC_VER >= 1800)
174# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2013, 0)
175#elif (_MSC_VER >= 1700)
176# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2012, 0)
177#elif (_MSC_VER >= 1600)
178# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2010, 0)
179#elif (_MSC_VER >= 1500)
180# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2008, 0)
181#else
182# define PLUGIFY_COMPILER_MSVC_VERSION PLUGIFY_COMPILER_MAKE_VERSION2(2005, 0)
183#endif
184#define PLUGIFY_MSVC_AT_LEAST(version, sp) (PLUGIFY_COMPILER_MSVC_VERSION >= PLUGIFY_COMPILER_MAKE_VERSION2((version), (sp)))
185#define PLUGIFY_MSVC_BEFORE(version, sp) (PLUGIFY_COMPILER_MSVC_VERSION < PLUGIFY_COMPILER_MAKE_VERSION2((version), (sp)))
186
187#if PLUGIFY_MSVC_BEFORE(2022, 9)
188#error "MSVC version 2022 17.13.0 required"
189#endif
190
191#endif
192
193// Define version detection for MSVC (_MSVC_LANG) and GCC/Clang (__cplusplus)
194#if defined(_MSC_VER) && defined(_MSVC_LANG)
195# define PLUGIFY_CPP_VERSION _MSVC_LANG
196#else
197# define PLUGIFY_CPP_VERSION __cplusplus
198#endif
199
200// Check for C++ version and define corresponding macros
201#if PLUGIFY_CPP_VERSION >= 202602L
202# define PLUGIFY_HAS_CXX26 1
203#endif
204
205#if PLUGIFY_CPP_VERSION >= 202302L
206# define PLUGIFY_HAS_CXX23 1
207#endif
208
209#define PLUGIFY_PRAGMA_IMPL(x) _Pragma(#x)
210#define PLUGIFY_PRAGMA(x) PLUGIFY_PRAGMA_IMPL(x)
211
212#if PLUGIFY_COMPILER_CLANG
213# define PLUGIFY_PRAGMA_DIAG_PREFIX clang
214#elif PLUGIFY_COMPILER_GCC
215# define PLUGIFY_PRAGMA_DIAG_PREFIX GCC
216#endif
217
218#if PLUGIFY_COMPILER_GCC || PLUGIFY_COMPILER_CLANG
219# define PLUGIFY_WARN_PUSH() PLUGIFY_PRAGMA(PLUGIFY_PRAGMA_DIAG_PREFIX diagnostic push)
220# define PLUGIFY_WARN_IGNORE(wrn) PLUGIFY_PRAGMA(PLUGIFY_PRAGMA_DIAG_PREFIX diagnostic ignored wrn)
221# define PLUGIFY_WARN_POP() PLUGIFY_PRAGMA(PLUGIFY_PRAGMA_DIAG_PREFIX diagnostic pop)
222#elif PLUGIFY_COMPILER_MSVC
223# define PLUGIFY_WARN_PUSH() __pragma(warning(push))
224# define PLUGIFY_WARN_IGNORE(wrn) __pragma(warning(disable: wrn))
225# define PLUGIFY_WARN_POP() __pragma(warning(pop))
226#endif
227
228#if PLUGIFY_COMPILER_GCC || PLUGIFY_COMPILER_CLANG
229# define PLUGIFY_PACK(decl) decl __attribute__((__packed__))
230#elif PLUGIFY_COMPILER_MSVC
231# define PLUGIFY_PACK(decl) __pragma(pack(push, 1)) decl __pragma(pack(pop))
232#else
233# define PLUGIFY_PACK(decl) decl
234#endif
235
236#if defined(_MSC_VER) && _MSC_VER >= 1929
237# define PLUGIFY_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]]
238#else
239# define PLUGIFY_NO_UNIQUE_ADDRESS [[no_unique_address]]
240#endif
241
242#if PLUGIFY_COMPILER_GCC || PLUGIFY_COMPILER_CLANG
243# define PLUGIFY_UNREACHABLE() __builtin_unreachable()
244#elif defined (_MSC_VER)
245# define PLUGIFY_UNREACHABLE() __assume(false)
246#else
247# define PLUGIFY_UNREACHABLE()
248#endif
249
250#if PLUGIFY_COMPILER_CLANG
251# define PLUGIFY_FORCE_INLINE [[gnu::always_inline]] [[gnu::gnu_inline]] extern inline
252# define PLUGIFY_NOINLINE [[gnu::noinline]]
253#elif PLUGIFY_COMPILER_GCC
254# define PLUGIFY_FORCE_INLINE [[gnu::always_inline]] inline
255# define PLUGIFY_NOINLINE [[gnu::noinline]]
256#elif PLUGIFY_COMPILER_MSVC
257# pragma warning(error: 4714)
258# define PLUGIFY_FORCE_INLINE __forceinline
259# define PLUGIFY_NOINLINE __declspec(noinline)
260#else
261# define PLUGIFY_FORCE_INLINE inline
262# define PLUGIFY_NOINLINE
263#endif
264
265#if PLUGIFY_COMPILER_GCC || PLUGIFY_COMPILER_CLANG
266# define PLUGIFY_RESTRICT __restrict__
267#elif PLUGIFY_COMPILER_MSVC
268# define PLUGIFY_RESTRICT __restrict
269#else
270# define PLUGIFY_RESTRICT
271#endif
272
273#if PLUGIFY_EXCEPTIONS
274template<typename E>
275[[noreturn]] PLUGIFY_FORCE_INLINE constexpr void plugify_throw(const char* msg) {
276 if constexpr (std::is_constructible_v<E, const char*>) {
277 throw E(msg);
278 } else {
279 throw E();
280 }
281}
282#endif