ARB
cxxforward.h
Go to the documentation of this file.
1 // ================================================================ //
2 // //
3 // File : cxxforward.h //
4 // Purpose : macros for forward usage of C++11 features //
5 // w/o loosing compatibility to C++03 compilers //
6 // //
7 // Coded by Ralf Westram (coder@reallysoft.de) in December 2012 //
8 // Institute of Microbiology (Technical University Munich) //
9 // http://www.arb-home.de/ //
10 // //
11 // ================================================================ //
12 
13 #ifndef CXXFORWARD_H
14 #define CXXFORWARD_H
15 
16 #ifndef GCCVER_H
17 #include "gccver.h"
18 #endif
19 #if defined(__cplusplus)
20 # if (GCC_VERSION_CODE >= 407)
21 # if (__cplusplus == 199711L)
22 # else
23 # if (__cplusplus == 201103L)
24 # define ARB_ENABLE11_FEATURES
25 # else
26 # if (__cplusplus == 201402L)
27 # define ARB_ENABLE14_FEATURES
28 # else
29 # if (__cplusplus == 201703L)
30 # define ARB_ENABLE17_FEATURES
31 # error ARB code does not support C++17 standard yet
32 // related to https://github.com/arb-project/homebrew-arb/issues/22 (see also mails from 24-May-2023)
33 # else
34 # error Unknown C++ standard defined in __cplusplus
35 # endif
36 # endif
37 # endif
38 # endif
39 # endif
40 #else
41 # error C compilation includes cxxforward.h
42 #endif
43 
44 #ifndef _GLIBCXX_CSTDDEF
45 #include <cstddef>
46 #endif
47 
48 // ---------------
49 // Cxx17
50 
51 #ifdef ARB_ENABLE17_FEATURES
52 # define ARB_ENABLE14_FEATURES
53 // no Cxx17 specifica used yet
54 #endif
55 
56 // ---------------
57 // Cxx14
58 
59 #ifdef ARB_ENABLE14_FEATURES
60 # define ARB_ENABLE11_FEATURES
61 // C++14 is enabled starting with gcc 6.1 in ../Makefile@USE_Cxx14
62 //
63 // Use #ifdef Cxx14 to insert conditional sections using full C++14
64 # define Cxx14 1
65 
66 // C++14 allows more complex constexpr functions (e.g. multiple commands; void return type)
67 # define CONSTEXPR_INLINE_Cxx14 constexpr inline
68 
69 #else
70 // backward (non C++14) compatibility defines:
71 
72 # define CONSTEXPR_INLINE_Cxx14 inline
73 
74 #endif
75 
76 // ---------------
77 // Cxx11
78 
79 #ifdef ARB_ENABLE11_FEATURES
80 // C++11 is enabled starting with gcc 4.7 in ../Makefile@USE_Cxx11
81 //
82 // Full support for C++11 is available starting with gcc 4.8.
83 // Use #ifdef Cxx11 to insert conditional sections using full C++11
84 # if (GCC_VERSION_CODE >= 408)
85 # define Cxx11 1
86 # endif
87 
88 // allows static member initialisation in class definition:
89 # define CONSTEXPR constexpr
90 # define CONSTEXPR_INLINE constexpr inline
91 
92 // allows to protect overloading functions against signature changes of overload functions:
93 # define OVERRIDE override
94 
95 // allows additional optimization of virtual calls
96 // (does not only allow to replace virtual by a normal call, it also allows inlining!)
97 # define FINAL_TYPE final
98 # define FINAL_OVERRIDE final override
99 
100 # define NULp nullptr
101 
102 #else
103 // backward (non C++11) compatibility defines:
104 
105 # if (GCC_VERSION_CODE >= 406)
106 # define CONSTEXPR constexpr
107 # else
108 # define CONSTEXPR const
109 # endif
110 
111 # define CONSTEXPR_INLINE inline
112 # define OVERRIDE
113 # define FINAL_TYPE
114 # define FINAL_OVERRIDE
115 
116 # define NULp NULL
117 // [Note: defining NULp as 0 causes failing tests if compiled with gcc 4.4.3; com-errors somewhere in AISC interface]
118 
119 #endif
120 
121 // Note: additional (experimental) constexpr macros are defined in ../CORE/arb_assert.h@ASSERTING_CONSTEXPR_INLINE
122 
123 
124 
125 // make use of gcc 7.x implicit fallthrough warnings:
126 #if (GCC_VERSION_CODE >= 700)
127 # define FALLTHROUGH [[gnu::fallthrough]]
128 // Note: Cxx17 may use [[fallthrough]]
129 #else
130 # define FALLTHROUGH
131 // Note: clang may know [[clang::fallthrough]]
132 #endif
133 
134 // hide warnings about intentionally unused things:
135 #if (GCC_VERSION_CODE >= 700)
136 # define UNUSED [[gnu::unused]]
137 // Note: Cxx17 may use [[unused]]
138 #else
139 # define UNUSED __attribute__((unused))
140 #endif
141 
142 
143 // allow to hide unwanted final suggestions
144 #ifdef SUGGESTS_FINAL
145 
146 # if (GCC_VERSION_CODE >= 900)
147 // test with older gcc versions?! SUGGESTS_FINAL defined for gcc 5.0++
148 # define EXTENDED_FINAL_WARNING_SUPPRESSION // gcc 9.1 became too smart (for old suppression methods)
149 # endif
150 
151 namespace final_unsuggest { struct fakedarg { }; };
152 # define NF_JOIN(X,Y) X##Y
153 
154 # ifdef EXTENDED_FINAL_WARNING_SUPPRESSION
155 
156 // declare fake-ctor used by MARK_NONFINAL_CLASS (has to be added into BASE)
157 # define PREPARE_MARK_NONFINAL_CLASS(CLASS) explicit CLASS(final_unsuggest::fakedarg)
158 
159 # define MARK_NONFINAL_CLASS(BASE) \
160  namespace final_unsuggest { \
161  struct UNUSED NF_JOIN(unfinalize,BASE) final : BASE { \
162  NF_JOIN(unfinalize,BASE)() : BASE(final_unsuggest::fakedarg()) {} \
163  }; \
164  }
165 
166 // PARAMS has to contain parentheses and attributes like const!
167 // RETURN has to contain 'return' keyword or may be completely empty
168 # define MARK_NONFINAL__INTERNAL(BASE,RETYPE,METHOD_NAME,PARAMS,RETURN) \
169  namespace final_unsuggest { \
170  struct UNUSED NF_JOIN(BASE,METHOD_NAME) final : BASE { \
171  RETYPE METHOD_NAME PARAMS override { \
172  RETURN; \
173  } \
174  }; \
175  }
176 
177 // some final type suggestion even do not get silenced by the above code.
178 // => disable -Wsuggest-final-types locally using
179 // GCC_TOO_SMART_FOR_USEFUL_FINAL_TYPE_SUGGESTION
180 
181 # if (GCC_VERSION_CODE >= 901) && (GCC_VERSION_CODE <= 905) // (please do not activate for all future versions, test each of them)
182 # define GCC_TOO_SMART_FOR_USEFUL_FINAL_TYPE_SUGGESTION
183 # endif
184 # if (GCC_VERSION_CODE >= 1001) && (GCC_VERSION_CODE <= 1005) // (please do not activate for all future versions, test each of them)
185 # define GCC_TOO_SMART_FOR_USEFUL_FINAL_TYPE_SUGGESTION
186 # endif
187 
188 # else // !EXTENDED_FINAL_WARNING_SUPPRESSION
189 
190 # define PREPARE_MARK_NONFINAL_CLASS(CLASS)
191 # define MARK_NONFINAL_CLASS(BASE) \
192  namespace final_unsuggest { \
193  struct UNUSED NF_JOIN(unfinalize,BASE) final : BASE { \
194  }; \
195  }
196 // PARAMS has to contain parentheses and attributes like const!
197 // RETURN is ignored here (needed in version above)
198 # define MARK_NONFINAL__INTERNAL(BASE,RETYPE,METHOD_NAME,PARAMS,RETURN) \
199  namespace final_unsuggest { \
200  struct UNUSED NF_JOIN(BASE,METHOD_NAME) final : BASE { \
201  inline RETYPE METHOD_NAME PARAMS override; \
202  }; \
203  }
204 
205 # endif
206 
207 #else
208 
209 # define PREPARE_MARK_NONFINAL_CLASS(CLASS)
210 # define MARK_NONFINAL_CLASS(BASE)
211 # define MARK_NONFINAL__INTERNAL(BASE,RETURN_TYPE,METHOD_NAME,PARAMS,RETURN)
212 
213 #endif
214 
215 
216 #define MARK_NONFINAL_DTOR(BASE) MARK_NONFINAL_CLASS(BASE)
217 
218 // like MARK_NONFINAL_FUNCTION, but void "result":
219 # define MARK_NONFINAL_FUNCTION(BASE,RETYPE,METHOD_NAME,PARAMS,RETVAL) MARK_NONFINAL__INTERNAL(BASE,RETYPE,METHOD_NAME,PARAMS,return RETVAL)
220 # define MARK_NONFINAL_METHOD(BASE,METHOD_NAME,PARAMS) MARK_NONFINAL__INTERNAL(BASE,void,METHOD_NAME,PARAMS,)
221 
222 
223 #undef ARB_ENABLE11_FEATURES
224 #undef ARB_ENABLE14_FEATURES
225 
226 #else
227 #error cxxforward.h included twice
228 #endif // CXXFORWARD_H