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