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
>
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_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
/** @} */
bsls_ident.h
BSLS_IDENT
#define BSLS_IDENT(str)
Definition
bsls_ident.h:195
doxygen_input
bde
groups
bsl
bsls
bsls_keyword.h
Generated by
1.9.8