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