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