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
>
12
BSLS_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
/** @} */
bsls_ident.h
BSLS_IDENT
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition
bsls_ident.h:238
doxygen_input
bde
groups
bsl
bsls
bsls_keyword.h
Generated by
1.9.8