BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bsls_keyword.h
Go to the documentation of this file.
1/// @file bsls_keyword.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bsls_keyword.h -*-C++-*-
8#ifndef INCLUDED_BSLS_KEYWORD
9#define INCLUDED_BSLS_KEYWORD
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bsls_keyword bsls_keyword
15/// @brief Provide macros for forward language dialect compatibility.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bsls
19/// @{
20/// @addtogroup bsls_keyword
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bsls_keyword-purpose"> Purpose</a>
25/// * <a href="#bsls_keyword-classes"> Classes </a>
26/// * <a href="#bsls_keyword-macros"> Macros </a>
27/// * <a href="#bsls_keyword-description"> Description </a>
28/// * <a href="#bsls_keyword-macro-summary"> Macro Summary </a>
29/// * <a href="#bsls_keyword-using-constexpr-macros-portably"> Using CONSTEXPR Macros Portably </a>
30/// * <a href="#bsls_keyword-constexpr-objects"> constexpr Objects </a>
31/// * <a href="#bsls_keyword-constexpr-functions"> constexpr Functions </a>
32/// * <a href="#bsls_keyword-usage"> Usage </a>
33/// * <a href="#bsls_keyword-example-1-preparing-c-03-code-for-c-11-features"> Example 1: Preparing C++03 Code for C++11 Features </a>
34/// * <a href="#bsls_keyword-example-2-creating-an-extended-constexpr-function"> Example 2: Creating an extended constexpr function </a>
35///
36/// # Purpose {#bsls_keyword-purpose}
37/// Provide macros for forward language dialect compatibility.
38///
39/// # Classes {#bsls_keyword-classes}
40///
41///
42/// # Macros {#bsls_keyword-macros}
43///
44/// - BSLS_KEYWORD_CONSTEVAL_CPP20: C++20 `consteval` keyword
45/// - BSLS_KEYWORD_CONSTEXPR: C++11 `constexpr` keyword
46/// - BSLS_KEYWORD_CONSTEXPR_MEMBER: for `constexpr` data members (Deprecated)
47/// - BSLS_KEYWORD_CONSTEXPR_RELAXED: C++14 `constexpr` keyword (Deprecated)
48/// - BSLS_KEYWORD_CONSTEXPR_CPP14: C++14 `constexpr` keyword
49/// - BSLS_KEYWORD_CONSTEXPR_CPP17: C++17 `constexpr` keyword
50/// - BSLS_KEYWORD_CONSTEXPR_CPP20: C++20 `constexpr` keyword
51/// - BSLS_KEYWORD_DELETED: C++11 `= delete` function definition
52/// - BSLS_KEYWORD_EXPLICIT: C++11 `explicit` for conversion operators
53/// - BSLS_KEYWORD_FINAL: C++11 `final` keyword
54/// - BSLS_KEYWORD_INLINE_CONSTEXPR: Do not use (Deprecated)
55/// - BSLS_KEYWORD_INLINE_VARIABLE: C++17 `inline` keyword for variables
56/// - BSLS_KEYWORD_NOEXCEPT: C++11 `noexcept` keyword
57/// - BSLS_KEYWORD_NOEXCEPT_AVAILABLE: `C++11` `noexcept` flag
58/// - BSLS_KEYWORD_NOEXCEPT_OPERATOR(expr): C++11 `noexcept` operation
59/// - BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(...): C++11 noexcept function qualifier
60/// - BSLS_KEYWORD_OVERRIDE: C++11 `override` keyword
61/// - BSLS_KEYWORD_THREAD_LOCAL: C++11 @ref thread_local keyword
62///
63/// # Description {#bsls_keyword-description}
64/// This component provides a suite of macros that simplify the use
65/// of language keywords that may not exist in all supported dialects of the C++
66/// language. For example, `BSLS_KEYWORD_NOEXCEPT` is replaced with `noexcept`
67/// on compilers supporting at least the C++11 language standard, and replaced
68/// with nothing on compilers supporting an older (e.g., C++03) standard. The
69/// goal is to allow implementation of components such that they can take
70/// advantage of some C++11 or later features when compiled with C++11 or later
71/// mode enabled while also correctly compiling in C++03 mode. The
72/// functionality of the respective features won't be available in C++03 mode.
73///
74/// ## Macro Summary {#bsls_keyword-macro-summary}
75///
76///
77/// The following are the macros provided by this component.
78///
79/// `BSLS_KEYWORD_CONSTEVAL_CPP20`:
80/// This macro inserts the keyword `consteval` when compiling with C++20
81/// or later mode and inserts nothing when compiling with earlier modes.
82///
83/// `BSLS_KEYWORD_CONSTEXPR`:
84/// This macro inserts the keyword `constexpr` when compiling with C++11
85/// or later mode and inserts nothing when compiling with C++03 mode.
86///
87/// `BSLS_KEYWORD_CONSTEXPR_MEMBER`:
88/// **DEPRECATED** See "Using CONSTEXPR Macros Portably" below. This macro
89/// inserts the keyword `constexpr` when compiling with C++11 or later mode
90/// and inserts the keyword `const` when compiling with C++03 mode. This
91/// macro was intended to support declaring static data members.
92///
93/// `BSLS_KEYWORD_CONSTEXPR_RELAXED`:
94/// **DEPRECATED** Use `BSLS_KEYWORD_CONSTEXPR_CPP14` instead. This macro
95/// inserts the keyword `constexpr` when compiling with C++14 or later mode
96/// and inserts nothing when compiling with C++03/C++11 mode.
97///
98/// `BSLS_KEYWORD_CONSTEXPR_CPP14`:
99/// This macro inserts the keyword `constexpr` when compiling with C++14
100/// or later mode and inserts nothing when compiling with C++03/C++11 mode.
101/// See Example 2 below for a better description of the differences between
102/// `constexpr` between C++11, C++14, and C++17.
103///
104/// `BSLS_KEYWORD_CONSTEXPR_CPP17`:
105/// This macro inserts the keyword `constexpr` when compiling with C++17
106/// or later mode and inserts nothing when compiling with C++03/C++11/C++14
107/// mode. See Example 2 below for a better description of the differences
108/// between `constexpr` between C++11, C++14, and C++17.
109///
110/// `BSLS_KEYWORD_CONSTEXPR_CPP20`:
111/// This macro inserts the keyword `constexpr` when compiling with C++20
112/// or later mode and inserts nothing when compiling with
113/// C++03/C++11/C++14/C++17 mode.
114///
115/// `BSLS_KEYWORD_DELETED`:
116/// This macro inserts the text `= delete` when compiling with C++11
117/// or later mode and inserts nothing when compiling with C++03 mode.
118///
119/// `BSLS_KEYWORD_EXPLICIT`:
120/// This macro inserts the keyword `explicit` when compiling with C++11
121/// or later mode and inserts nothing when compiling with C++03 mode.
122///
123/// `BSLS_KEYWORD_FINAL`:
124/// This macro inserts the keyword `final` when compiling with C++11 or
125/// later mode and inserts nothing when compiling with C++03 mode.
126///
127/// `BSLS_KEYWORD_INLINE_CONSTEXPR`
128/// **DEPRECATED** THIS MACRO CANNOT BE USED SAFELY ACROSS MULTIPLE LANGUAGE
129/// VERSIONS. This macro inserted the keywords `inline constexpr` when
130/// compiled with C++17 or later mode and inserted the best approximation
131/// in earlier dialects, ultimately degrading down to `static const` in
132/// C++03.
133///
134/// `BSLS_KEYWORD_INLINE_VARIABLE`
135/// This macro inserts the keyword `inline` when compiling with C++17 or
136/// later mode and inserts nothing when compiling with C++03/C++11/C++14
137/// mode.
138///
139/// `BSLS_KEYWORD_NOEXCEPT`:
140/// This macro inserts the keyword `noexcept` when compiling with C++11
141/// or later mode and inserts nothing when compiling with C++03 mode.
142///
143/// `BSLS_KEYWORD_NOEXCEPT_AVAILABLE`:
144/// This macro expands to `true` when the `noexcept` feature is available
145/// and `false` otherwise.
146///
147/// `BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(BOOL_EXPRESSION)`:
148/// This macro inserts the exception specification
149/// `noexcept(BOOL_EXPRESSION)` when compiling with C++11 or later mode and
150/// inserts nothing when compiling with C++03 mode. This macro is used to
151/// specify which version of noexcept is intended when multiple `noexcept`s
152/// are used in a single statement.
153///
154/// `BSLS_KEYWORD_NOEXCEPT_OPERATOR(expr)`:
155/// This macro inserts the operation `noexcept(expr)` when compiling with
156/// C++11 or later mode and inserts the literal `false` when compiling with
157/// C++03 mode.
158///
159/// `BSLS_KEYWORD_OVERRIDE`
160/// This macro inserts the keyword `override` when compiling with C++11
161/// or later mode and inserts nothing when compiling with C++03 mode.
162///
163/// `BSLS_KEYWORD_THREAD_LOCAL`
164/// This macro inserts the keyword @ref thread_local when compiling with C++11
165/// or later mode and inserts a non-standard compiler-specific keyword in
166/// C++03 mode. **Note that** the behaviour of the non-standard keyword is
167/// slightly different:
168/// 1) It does not imply `static` at block scope; therefore `static`
169/// must always be specified explicitly on block-scope declarations
170/// that use `BSLS_KEYWORD_THREAD_LOCAL`;
171/// 2) The initializer must be a compile-time constant expression.
172/// Note that C++03 does not have `constexpr` functions, so the
173/// initializer cannot contain any explicit function calls. If the
174/// variable is of class type, a nontrivial constructor cannot be
175/// used, and the destructor must be trivial. Also note that, in
176/// order to produce a constant expression, it is not necessary to
177/// provide an explicit value for the variable or for all its
178/// members, due to the implicit zero-initialization of thread-local
179/// variables.
180///
181/// ## Using CONSTEXPR Macros Portably {#bsls_keyword-using-constexpr-macros-portably}
182///
183///
184/// The `constexpr` keyword has changed more across different versions of the
185/// C++ standard than most keywords, and its usage in portable code is
186/// complicated. The following rules apply when the `constexpr` keyword
187/// provides potential optimizations where supported, but backwards
188/// compatibility to C++03 is required.
189///
190/// ### constexpr Objects {#bsls_keyword-constexpr-objects}
191///
192///
193/// Namespace scope objects in source files, and block scope objects, should be
194/// declared with the `const` keyword and the `BSLS_KEYWORD_CONSTEXPR` macro.
195/// The `const` keyword is redundant but not problematic where the macro expands
196/// to `constexpr`.
197/// @code
198/// // abc_mycomponent.cpp
199/// const BSLS_KEYWORD_CONSTEXPR double pi = 3.14;
200///
201/// void f()
202/// {
203/// const BSLS_KEYWORD_CONSTEXPR double euler = 2.718;
204/// }
205/// @endcode
206/// Namespace scope objects in header files that are `constexpr` and not
207/// `inline` are dangerous, as there's no way to prevent undiagnosed ODR
208/// violations in inline functions that ODR-use the variable. If you require a
209/// constant object with external linkage (appearing in a header file and used
210/// by multiple translation units) it is suggested that you use `constexpr` only
211/// where `inline` variables are permitted.
212/// @code
213/// // abc_somecomponent.h
214/// #ifdef BSLS_COMPILERFEATURES_SUPPORT_INLINE_VARIABLES
215/// inline constexpr double pi = 3.14;
216/// #else
217/// extern const double pi;
218/// #endif
219/// @endcode
220/// And:
221/// @code
222/// // abc_somecomponent.cpp
223/// #ifndef BSLS_COMPILERFEATURES_SUPPORT_INLINE_VARIABLES
224/// extern const double pi = 3.14;
225/// #endif
226/// @endcode
227/// Integral or enumeration type static data members of non-template classes
228/// should be declared with the `const` keyword. There is no benefit to them
229/// being `constexpr`, as `const` variables of integral type can be used in
230/// constant expressions. An out-of-line definition is required in exactly one
231/// source file.
232/// @code
233/// // abc_mycomponent.h
234/// class MyComponent {
235/// // ...
236/// public:
237/// static const int s_feetInMile = 5280;
238/// };
239/// @endcode
240/// And:
241/// @code
242/// // abc_mycomponent.cpp
243/// const int MyComponent::s_feetInMile;
244/// @endcode
245/// Integral or enumeration type static data members of class templates should
246/// be declared with the `const` keyword, and should provide an out-of-line
247/// definition in the same file.
248/// @code
249/// // abc_mytemplatedcomponent.h
250/// template <class TYPE>
251/// class MyTemplatedComponent {
252/// // ...
253/// public:
254/// static const int s_ouncesInPound = 16;
255/// };
256///
257/// template <class TYPE>
258/// const int MyTemplatedComponent<TYPE>::s_ouncesInPound;
259/// @endcode
260/// Static data members of non-integral type cannot make use of `constexpr`
261/// keyword macros, as the initialization of the variable must take place in
262/// line for `constexpr` and out of line for `const`.
263/// @code
264/// // abc_myothercomponent.h
265/// class MyOtherComponent {
266/// // ...
267/// public:
268/// #ifdef BSLS_COMPILERFEATURES_SUPPORT_CONSTEXPR
269/// static constexpr double s_pi = 3.14;
270/// #else
271/// static const double s_pi;
272/// #endif
273/// };
274/// @endcode
275/// And:
276/// @code
277/// // abc_myothercomponent.cpp
278/// #ifdef BSLS_COMPILERFEATURES_SUPPORT_CONSTEXPR
279/// static constexpr double MyOtherComponent::s_pi;
280/// #else
281/// static const double MyOtherComponent::s_pi = 3.14;
282/// #endif
283/// @endcode
284///
285/// ### constexpr Functions {#bsls_keyword-constexpr-functions}
286///
287///
288/// All functions declared with any `BSLS_KEYWORD_CONSTEXPR` macro must be
289/// defined with the `inline` keyword to work correctly in C++03 or any other
290/// build mode where the macro expands to nothing, unless the function has
291/// internal linkage, is defined inside a class definition, or is a template.
292/// @code
293/// // abc_mycomponentutil.h
294/// inline BSLS_KEYWORD_CONSTEXPR int doubleTheInt(int i)
295/// {
296/// return 2 * i;
297/// }
298/// @endcode
299/// As standards progressed, more and more things were allowed to take place
300/// within `constexpr` functions. Depending on what a given function needs to
301/// do, it may be eligible to be marked `constexpr` in only a certain standard
302/// or later, and this is exactly what the macros appended with _CPPxx are for.
303/// @code
304/// inline BSLS_KEYWORD_CONSTEXPR_CPP14 int doubleTheInt(int i)
305/// {
306/// int x = i * 2; // Can't declare variables in C++11 constexpr functions
307/// return x;
308/// }
309/// @endcode
310/// All `constexpr` non-static member functions in C++11 are implicitly const,
311/// so a member function using the `BSLS_KEYWORD_CONSTEXPR` macro should also be
312/// marked `const` so that non-const usage of `*this` will be identified in
313/// other build modes. If the method is required to be non-`const`, then it
314/// cannot be `constexpr` in C++11, and `BSLS_KEYWORD_CONSTEXPR_CPP14` should be
315/// used.
316/// @code
317/// class ComponentWithCpp11ConstexprMethod {
318/// // ...
319/// public:
320/// BSLS_KEYWORD_CONSTEXPR int cpp11ConstexprMethod() const;
321/// }
322///
323/// inline BSLS_KEYWORD_CONSTEXPR
324/// int ComponentWithCpp11ConstexprMethod::cpp11ConstexprMethod() const
325/// {
326/// // ...
327/// }
328/// @endcode
329///
330/// ## Usage {#bsls_keyword-usage}
331///
332///
333/// This section illustrates intended use of this component.
334///
335/// ### Example 1: Preparing C++03 Code for C++11 Features {#bsls_keyword-example-1-preparing-c-03-code-for-c-11-features}
336///
337///
338/// To use these macros, simply insert them where the corresponding C++11
339/// keyword would go. When compiling with C++03 mode there will be no effect
340/// but when compiling with C++11 mode additional restrictions will apply. When
341/// compiling with C++11 mode the restriction will be checked providing some
342/// additional checking over what is done with C++11.
343///
344/// C++ uses the `explicit` keyword to indicate that constructors taking just
345/// one argument are not considered for implicit conversions. Instead, they can
346/// only be used for explicit conversions. C++ also provides the ability to
347/// define conversion operators but prior to C++11 these conversion operators
348/// are considered for implicit conversion. C++11 allows the use of the
349/// `explicit` keyword with conversion operators to avoid its use for implicit
350/// conversions. The macro `BSLS_KEYWORD_EXPLICIT` can be used to mark
351/// conversions as explicit conversions that will be checked when compiling with
352/// C++11 mode. For example, an `Optional` type may have an explicit conversion
353/// to `bool` to indicate that the value is set (note the conversion operator):
354/// @code
355/// template <class TYPE>
356/// class Optional
357/// {
358/// TYPE* d_value_p;
359/// public:
360/// Optional(): d_value_p() {}
361/// explicit Optional(const TYPE& value): d_value_p(new TYPE(value)) {}
362/// ~Optional() { delete d_value_p; }
363/// // ...
364///
365/// BSLS_KEYWORD_EXPLICIT operator bool() const { return d_value_p; }
366/// };
367/// @endcode
368/// When using an object of the `Optional` class in a condition it is desirable
369/// that it converts to a `bool`:
370/// @code
371/// void testFunction() {
372/// Optional<int> value;
373/// if (value) { /*... */ }
374/// @endcode
375/// In places where an implicit conversion takes place it is not desirable that
376/// the conversion is used. When compiling with C++11 mode the conversion
377/// operator will not be used, e.g., the following code will result in an error:
378/// @code
379/// #if BSLS_COMPILERFEATURES_CPLUSPLUS < 201103L
380/// bool flag = value;
381/// #endif
382/// }
383/// @endcode
384/// The code will compile successfully when using C++03 mode; without the macro,
385/// when using C++11 or greater mode we get an error like this:
386/// @code
387/// error: cannot convert 'Optional<int>' to 'bool' in initialization
388/// @endcode
389///
390/// When defining conversion operators to `bool` for code that needs to compile
391/// with C++03 mode the conversion operator should convert to a member pointer
392/// type instead: doing so has a similar effect to making the conversion
393/// operator `explicit`.
394///
395/// Some classes are not intended for use as a base class. To clearly label
396/// these classes and enforce that they can't be derived from C++11 allows using
397/// the `final` keyword after the class name in the class definition to label
398/// classes that are not intended to be derived from. The macro
399/// `BSLS_KEYWORD_FINAL` is replaced by `final` when compiling with C++11
400/// causing the compiler to enforce that a class can't be further derived. The
401/// code below defines a class that can't be derived from:
402/// @code
403/// class FinalClass BSLS_KEYWORD_FINAL
404/// {
405/// int d_value;
406/// public:
407/// explicit FinalClass(int value = 0): d_value(value) {}
408/// int value() const { return d_value; }
409/// };
410/// @endcode
411/// An attempt to derive from this class will fail when compiling with C++11
412/// mode:
413/// @code
414/// #if BSLS_COMPILERFEATURES_CPLUSPLUS < 201103L
415/// class FinalClassDerived : public FinalClass {
416/// int d_anotherValue;
417/// public:
418/// explicit FinalClassDerived(int value)
419/// : d_anotherValue(2 * value) {
420/// }
421/// int anotherValue() const { return d_anotherValue; }
422/// };
423/// #endif
424/// @endcode
425/// The code will compile successfully when using C++03 mode; without the macro,
426/// when using C++11 or greater mode we get an error like this:
427/// @code
428/// error: cannot derive from 'final' base 'FinalClass' in derived type
429/// 'FinalClassDerived'
430/// @endcode
431///
432/// Sometime it is useful to declare that an overriding function is the final
433/// overriding function and further derived classes won't be allowed to further
434/// override the function. One use of this feature could be informing the
435/// compiler that it won't need to use virtual dispatch when calling this
436/// function on a pointer or a reference of the corresponding type. C++11
437/// allows marking functions as the final overrider using the keyword `final`.
438/// The macro `BSLS_KEYWORD_FINAL` can also be used for this purpose. To
439/// demonstrate the use of this keyword first a base class with a `virtual`
440/// function is defined:
441/// @code
442/// struct FinalFunctionBase
443/// {
444/// virtual int f() { return 0; }
445/// };
446/// @endcode
447/// When defining a derived class this function `f` can be marked as the final
448/// overrider using `BSLS_KEYWORD_FINAL`:
449/// @code
450/// struct FinalFunctionDerived: FinalFunctionBase
451/// {
452/// int f() BSLS_KEYWORD_FINAL { return 1; }
453/// };
454/// @endcode
455/// The semantics of the overriding function aren't changed but a further
456/// derived class can't override the function `f`, i.e., the following code will
457/// result in an error when compiling with C++11 mode:
458/// @code
459/// #if BSLS_COMPILERFEATURES_CPLUSPLUS < 201103L
460/// struct FinalFunctionFailure: FinalFunctionDerived
461/// {
462/// int f() { return 2; }
463/// };
464/// #endif
465/// @endcode
466/// The code will compile successfully when using C++03 mode; without the macro,
467/// when using C++11 or greater mode we get an error like this:
468/// @code
469/// error: virtual function 'virtual int FinalFunctionFailure::f()'
470/// error: overriding final function 'virtual int FinalFunctionDerived::f()'
471/// @endcode
472///
473/// The C++11 keyword `override` is used to identify functions overriding a
474/// `virtual` function from a base class. If a function identified as
475/// `override` does not override a `virtual` function from a base class the
476/// compilation results in an error. The macro `BSLS_KEYWORD_OVERRIDE` is used
477/// to insert the `override` keyword when compiling with C++11 mode. When
478/// compiling with C++03 mode it has no effect but it both cases it documents
479/// that a function is overriding a `virtual` function from a base class. To
480/// demonstrate the use of the `BSLS_KEYWORD_OVERRIDE` macro first a base class
481/// is defined:
482/// @code
483/// struct OverrideBase
484/// {
485/// virtual int f() const { return 0; }
486/// };
487/// @endcode
488/// When overriding `OverrideBase::f` in a derived class the
489/// `BSLS_KEYWORD_OVERRIDE` macro should be used to ascertain that the function
490/// in the derived class is indeed overriding a `virtual` function:
491/// @code
492/// struct OverrideSuccess: OverrideBase
493/// {
494/// int f() const BSLS_KEYWORD_OVERRIDE { return 1; }
495/// };
496/// @endcode
497/// The above code compiles successfully with both C++03 mode and C++11. When
498/// the function meant to be an override actually isn't overriding any function
499/// the compilation will fail when using C++11 mode as is demonstrated by the
500/// following example (note the missing `const` in the function declaration):
501/// @code
502/// #if BSLS_COMPILERFEATURES_CPLUSPLUS < 201103L
503/// struct OverrideFailure: OverrideBase
504/// {
505/// int f() BSLS_KEYWORD_OVERRIDE { return 2; }
506/// };
507/// #endif
508/// @endcode
509/// The code will compile successfully when using C++03 mode (though it might
510/// produce a warning); without the macro, when using C++11 or greater mode we
511/// get an error like this:
512/// @code
513/// error: 'int OverrideFailure::f()' marked 'override', but does not
514/// override
515/// @endcode
516///
517/// ### Example 2: Creating an extended constexpr function {#bsls_keyword-example-2-creating-an-extended-constexpr-function}
518///
519///
520/// To use these macros, simply insert them where the corresponding C++14
521/// keyword would go. When compiling with C++03 or C++11 mode there will be no
522/// effect but when compiling with C++14 mode additional restrictions will
523/// apply. When compiling with C++14 mode the restriction will be checked
524/// providing some additional checking over what is done with C++11 or C++03.
525///
526/// C++11 uses the `constexpr` keyword to indicate that a (very simple) function
527/// may be evaluated compile-time if all its input is known compile time. C++14
528/// allows more complex functions to be `constexpr`. Also, in C++14,
529/// `constexpr` member functions are not implicitly `const` as in C++11.
530/// Thefore we have a separate macro `BSLS_KEYWORD_CONSTEXPR_CPP14` that can be
531/// used to mark functions `constexpr` when compiling with C++14 mode:
532/// @code
533/// BSLS_KEYWORD_CONSTEXPR_CPP14
534/// int complexConstexprFunc(bool b)
535/// {
536/// if (b) {
537/// return 42; // RETURN
538/// }
539/// else {
540/// return 17; // RETURN
541/// }
542/// }
543/// @endcode
544/// When compiling with C++14 `constexpr` support it is possible to use the
545/// result of `complexConstexprFunc` in compile-time constants:
546/// @code
547/// void useComplexConstexprFunc()
548/// {
549/// #ifdef BSLS_COMPILERFEATURES_SUPPORT_CONSTEXPR_CPP14
550/// constexpr
551/// #endif
552/// int result = complexConstexprFunc(true);
553/// ASSERT(42 == result);
554/// @endcode
555/// The macro `BSLS_KEYWORD_CONSTEXPR_CPP14` can also be used on variables to
556/// achieve an identical result:
557/// @code
558/// BSLS_KEYWORD_CONSTEXPR_CPP14 int result2 = complexConstexprFunc(true);
559/// ASSERT(42 == result2);
560/// }
561/// @endcode
562/// C++17 made small but significant changes to what is allowed in a `constexpr`
563/// function. Notably, a lambda can now be defined in such a function (and, if
564/// not called at compile time, does not itself need to be `constexpr`). To
565/// take advantage of this there is a separate macro
566/// `BSLS_KEYWORD_CONSTEXPR_CPP17` that can be used to mark functions
567/// `constexpr` when compiling with C++17 mode:
568/// @code
569/// BSLS_KEYWORD_CONSTEXPR_CPP17
570/// int moreComplexConstexprFunc(bool b)
571/// {
572/// if (b) {
573/// return 42; // RETURN
574/// }
575/// else {
576/// #if BSLS_COMPILERFEATURES_CPLUSPLUS >= 201103L
577/// return []{
578/// static int b = 17;
579/// return b;
580/// }(); // RETURN
581/// #else
582/// return 17;
583/// #endif
584/// }
585/// }
586/// @endcode
587/// Then, just like `useComplexConstexprFunc`, we can invoke
588/// `moreComplexConstexprFunc` to populate a compile-time constant when it is
589/// supported:
590/// @code
591/// void useMoreComplexConstexprFunc()
592/// {
593/// BSLS_KEYWORD_CONSTEXPR_CPP17 int result
594/// = moreComplexConstexprFunc(true);
595/// ASSERT(42 == result);
596/// }
597/// @endcode
598/// @}
599/** @} */
600/** @} */
601
602/** @addtogroup bsl
603 * @{
604 */
605/** @addtogroup bsls
606 * @{
607 */
608/** @addtogroup bsls_keyword
609 * @{
610 */
611
612#include <bsls_compilerfeatures.h>
613
614#ifdef BSLS_COMPILERFEATURES_SUPPORT_CONSTEVAL_CPP20
615# define BSLS_KEYWORD_CONSTEVAL_CPP20 consteval
616#else
617# define BSLS_KEYWORD_CONSTEVAL_CPP20
618#endif
619
620#ifdef BSLS_COMPILERFEATURES_SUPPORT_CONSTEXPR
621# define BSLS_KEYWORD_CONSTEXPR constexpr
622# define BSLS_KEYWORD_CONSTEXPR_MEMBER constexpr
623#else
624# define BSLS_KEYWORD_CONSTEXPR
625# define BSLS_KEYWORD_CONSTEXPR_MEMBER const
626#endif
627
628#ifdef BSLS_COMPILERFEATURES_SUPPORT_CONSTEXPR_CPP14
629# define BSLS_KEYWORD_CONSTEXPR_CPP14 constexpr
630#else
631# define BSLS_KEYWORD_CONSTEXPR_CPP14
632#endif
633
634# define BSLS_KEYWORD_CONSTEXPR_RELAXED BSLS_KEYWORD_CONSTEXPR_CPP14
635
636#ifdef BSLS_COMPILERFEATURES_SUPPORT_CONSTEXPR_CPP17
637# define BSLS_KEYWORD_CONSTEXPR_CPP17 constexpr
638#else
639# define BSLS_KEYWORD_CONSTEXPR_CPP17
640#endif
641
642#ifdef BSLS_COMPILERFEATURES_SUPPORT_CONSTEXPR_CPP20
643#define BSLS_KEYWORD_CONSTEXPR_CPP20 constexpr
644#else
645#define BSLS_KEYWORD_CONSTEXPR_CPP20
646#endif
647
648#ifdef BSLS_COMPILERFEATURES_SUPPORT_DELETED_FUNCTIONS
649# define BSLS_KEYWORD_DELETED = delete
650#else
651# define BSLS_KEYWORD_DELETED
652#endif
653
654#ifdef BSLS_COMPILERFEATURES_SUPPORT_INLINE_CONSTEXPR
655# define BSLS_KEYWORD_INLINE_CONSTEXPR inline constexpr
656#elif defined(BSLS_COMPILERFEATURES_SUPPORT_CONSTEXPR)
657# define BSLS_KEYWORD_INLINE_CONSTEXPR constexpr
658#else
659# define BSLS_KEYWORD_INLINE_CONSTEXPR static const
660#endif
661
662#ifdef BSLS_COMPILERFEATURES_SUPPORT_INLINE_VARIABLES
663# define BSLS_KEYWORD_INLINE_VARIABLE inline
664#else
665# define BSLS_KEYWORD_INLINE_VARIABLE
666#endif
667
668#ifdef BSLS_COMPILERFEATURES_SUPPORT_NOEXCEPT
669# define BSLS_KEYWORD_NOEXCEPT noexcept
670# define BSLS_KEYWORD_NOEXCEPT_AVAILABLE true
671# define BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(...) noexcept(__VA_ARGS__)
672# define BSLS_KEYWORD_NOEXCEPT_OPERATOR(...) noexcept(__VA_ARGS__)
673#else
674# define BSLS_KEYWORD_NOEXCEPT
675# define BSLS_KEYWORD_NOEXCEPT_AVAILABLE false
676# define BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(...)
677# define BSLS_KEYWORD_NOEXCEPT_OPERATOR(...) false
678#endif
679
680#ifdef BSLS_COMPILERFEATURES_SUPPORT_OPERATOR_EXPLICIT
681# define BSLS_KEYWORD_EXPLICIT explicit
682#else
683# define BSLS_KEYWORD_EXPLICIT
684#endif
685
686#ifdef BSLS_COMPILERFEATURES_SUPPORT_FINAL
687# define BSLS_KEYWORD_FINAL final
688#else
689# define BSLS_KEYWORD_FINAL
690#endif
691
692#ifdef BSLS_COMPILERFEATURES_SUPPORT_OVERRIDE
693# define BSLS_KEYWORD_OVERRIDE override
694#else
695# define BSLS_KEYWORD_OVERRIDE
696#endif
697
698#if BSLS_COMPILERFEATURES_CPLUSPLUS >= 201103L
699# define BSLS_KEYWORD_THREAD_LOCAL thread_local
700#else
701# define BSLS_KEYWORD_THREAD_LOCAL __thread
702#endif
703
704// ----------------------------------------------------------------------------
705
706#endif
707
708// ----------------------------------------------------------------------------
709// Copyright 2018 Bloomberg Finance L.P.
710//
711// Licensed under the Apache License, Version 2.0 (the "License");
712// you may not use this file except in compliance with the License.
713// You may obtain a copy of the License at
714//
715// http://www.apache.org/licenses/LICENSE-2.0
716//
717// Unless required by applicable law or agreed to in writing, software
718// distributed under the License is distributed on an "AS IS" BASIS,
719// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
720// See the License for the specific language governing permissions and
721// limitations under the License.
722// ----------------------------- END-OF-FILE ----------------------------------
723
724/** @} */
725/** @} */
726/** @} */
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238