|
22 | 22 | # pragma system_header |
23 | 23 | #endif // no system header |
24 | 24 |
|
| 25 | +/////////////////////////////////////////////////////////////////////////////// |
| 26 | +// Determine the C++ standard dialect |
| 27 | +/////////////////////////////////////////////////////////////////////////////// |
25 | 28 | #if _CCCL_COMPILER(MSVC) |
26 | 29 | # if _MSVC_LANG <= 201103L |
27 | 30 | # define _CCCL_STD_VER 2011 |
|
52 | 55 | # endif |
53 | 56 | #endif // !_CCCL_COMPILER(MSVC) |
54 | 57 |
|
| 58 | +/////////////////////////////////////////////////////////////////////////////// |
| 59 | +// Conditionally enable constexpr per standard dialect |
| 60 | +/////////////////////////////////////////////////////////////////////////////// |
55 | 61 | #if _CCCL_STD_VER >= 2014 |
56 | 62 | # define _CCCL_CONSTEXPR_CXX14 constexpr |
57 | 63 | #else // ^^^ C++14 ^^^ / vvv C++11 vvv |
|
76 | 82 | # define _CCCL_CONSTEXPR_CXX23 |
77 | 83 | #endif // _CCCL_STD_VER <= 2020 |
78 | 84 |
|
79 | | -#if _CCCL_STD_VER >= 2017 && defined(__cpp_if_constexpr) |
80 | | -# define _CCCL_IF_CONSTEXPR if constexpr |
81 | | -#else // ^^^ C++17 ^^^ / vvv C++14 vvv |
| 85 | +/////////////////////////////////////////////////////////////////////////////// |
| 86 | +// Detect whether we can use some language features based on standard dialect |
| 87 | +/////////////////////////////////////////////////////////////////////////////// |
| 88 | +#if _CCCL_STD_VER <= 2014 || __cpp_if_constexpr < 201606L |
82 | 89 | # define _CCCL_NO_IF_CONSTEXPR |
83 | | -# define _CCCL_IF_CONSTEXPR if |
84 | | -#endif // _CCCL_STD_VER <= 2014 |
| 90 | +#endif // _CCCL_STD_VER <= 2014 || !defined(__cpp_if_constexpr) |
85 | 91 |
|
86 | | -// In nvcc prior to 11.3 global variables could not be marked constexpr |
87 | | -#if _CCCL_CUDACC_BELOW(11, 3) |
88 | | -# define _CCCL_CONSTEXPR_GLOBAL const |
89 | | -#else // ^^^ _CCCL_CUDACC_BELOW(11, 3) ^^^ / vvv _CCCL_CUDACC_AT_LEAST(11, 3) vvv |
90 | | -# define _CCCL_CONSTEXPR_GLOBAL constexpr |
91 | | -#endif // _CCCL_CUDACC_AT_LEAST(11, 3) |
| 92 | +// concepts are only available from C++20 onwards |
| 93 | +#if _CCCL_STD_VER <= 2017 || __cpp_concepts < 201907L |
| 94 | +# define _CCCL_NO_CONCEPTS |
| 95 | +#endif // _CCCL_STD_VER <= 2017 || __cpp_concepts < 201907L |
| 96 | + |
| 97 | +// CTAD is only available from C++17 onwards |
| 98 | +#if _CCCL_STD_VER <= 2014 || __cpp_deduction_guides < 201611L |
| 99 | +# define _CCCL_NO_DEDUCTION_GUIDES |
| 100 | +#endif // _CCCL_STD_VER <= 2014 || __cpp_deduction_guides < 201611L |
| 101 | + |
| 102 | +// Fold expressions are only available from C++17 onwards |
| 103 | +#if _CCCL_STD_VER <= 2014 || __cpp_fold_expressions < 201603L |
| 104 | +# define _CCCL_NO_FOLD_EXPRESSIONS |
| 105 | +#endif // _CCCL_STD_VER <= 2014 || __cpp_fold_expressions < 201603L |
92 | 106 |
|
93 | 107 | // Inline variables are only available from C++17 onwards |
94 | | -#if _CCCL_STD_VER >= 2017 && defined(__cpp_inline_variables) && (__cpp_inline_variables >= 201606L) |
95 | | -# define _CCCL_INLINE_VAR inline |
96 | | -#else // ^^^ C++17 ^^^ / vvv C++14 vvv |
| 108 | +#if _CCCL_STD_VER <= 2014 || __cpp_inline_variables < 201606L |
97 | 109 | # define _CCCL_NO_INLINE_VARIABLES |
98 | | -# define _CCCL_INLINE_VAR |
99 | | -#endif // _CCCL_STD_VER <= 2014 |
| 110 | +#endif // _CCCL_STD_VER <= 2014 || __cpp_inline_variables < 201606L |
100 | 111 |
|
101 | | -// Variable templates are only available from C++14 onwards and require some compiler support |
102 | | -#if _CCCL_STD_VER <= 2011 || !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304L) |
103 | | -# define _CCCL_NO_VARIABLE_TEMPLATES |
104 | | -#endif // _CCCL_STD_VER <= 2011 |
| 112 | +// noexcept function types are only available from C++17 onwards |
| 113 | +#if _CCCL_STD_VER <= 2014 || __cpp_noexcept_function_type < 201510L |
| 114 | +# define _CCCL_NO_NOEXCEPT_FUNCTION_TYPE |
| 115 | +#endif // _CCCL_STD_VER <= 2014 || __cpp_noexcept_function_type < 201510L |
105 | 116 |
|
106 | 117 | // Declaring a non-type template parameters with auto is only available from C++17 onwards |
107 | | -#if _CCCL_STD_VER >= 2017 && defined(__cpp_nontype_template_parameter_auto) \ |
108 | | - && (__cpp_nontype_template_parameter_auto >= 201606L) |
109 | | -# define _CCCL_NTTP_AUTO auto |
110 | | -#else // ^^^ C++17 ^^^ / vvv C++14 vvv |
| 118 | +#if _CCCL_STD_VER <= 2014 || __cpp_nontype_template_parameter_auto < 201606L |
111 | 119 | # define _CCCL_NO_NONTYPE_TEMPLATE_PARAMETER_AUTO |
112 | | -# define _CCCL_NTTP_AUTO unsigned long long int |
113 | | -#endif // _CCCL_STD_VER <= 2014 |
| 120 | +#endif // _CCCL_STD_VER <= 2014 || __cpp_nontype_template_parameter_auto < 201606L |
114 | 121 |
|
115 | | -// concepts are only available from C++20 onwards |
116 | | -#if _CCCL_STD_VER <= 2017 || !defined(__cpp_concepts) || (__cpp_concepts < 201907L) |
117 | | -# define _CCCL_NO_CONCEPTS |
118 | | -#endif // _CCCL_STD_VER <= 2017 || !defined(__cpp_concepts) || (__cpp_concepts < 201907L) |
| 122 | +// Three way comparison is only available from C++20 onwards |
| 123 | +#if _CCCL_STD_VER <= 2017 || __cpp_three_way_comparison < 201907 |
| 124 | +# define _CCCL_NO_THREE_WAY_COMPARISON |
| 125 | +#endif // _CCCL_STD_VER <= 2017 || __cpp_three_way_comparison < 201907 |
119 | 126 |
|
120 | | -// noexcept function types are only available from C++17 onwards |
121 | | -#if _CCCL_STD_VER >= 2017 && defined(__cpp_noexcept_function_type) && (__cpp_noexcept_function_type >= 201510L) |
122 | | -# define _CCCL_FUNCTION_TYPE_NOEXCEPT noexcept |
123 | | -#else // ^^^ C++17 ^^^ / vvv C++14 vvv |
124 | | -# define _CCCL_NO_NOEXCEPT_FUNCTION_TYPE |
| 127 | +// Variable templates are only available from C++14 onwards and require some compiler support |
| 128 | +#if _CCCL_STD_VER <= 2011 || __cpp_variable_templates < 201304L |
| 129 | +# define _CCCL_NO_VARIABLE_TEMPLATES |
| 130 | +#endif // _CCCL_STD_VER <= 2011 || __cpp_variable_templates < 201304L |
| 131 | + |
| 132 | +/////////////////////////////////////////////////////////////////////////////// |
| 133 | +// Conditionally use certain language features depending on availablility |
| 134 | +/////////////////////////////////////////////////////////////////////////////// |
| 135 | +#if defined(_CCCL_NO_IF_CONSTEXPR) |
| 136 | +# define _CCCL_IF_CONSTEXPR if |
| 137 | +#else // ^^^ _CCCL_NO_IF_CONSTEXPR ^^^ / vvv !_CCCL_NO_IF_CONSTEXPR vvv |
| 138 | +# define _CCCL_IF_CONSTEXPR if constexpr |
| 139 | +#endif // !_CCCL_NO_IF_CONSTEXPR |
| 140 | + |
| 141 | +#if defined(_CCCL_NO_INLINE_VARIABLES) |
| 142 | +# define _CCCL_INLINE_VAR |
| 143 | +#else // ^^^ _CCCL_NO_INLINE_VARIABLES ^^^ / vvv !_CCCL_NO_INLINE_VARIABLES vvv |
| 144 | +# define _CCCL_INLINE_VAR inline |
| 145 | +#endif // !_CCCL_NO_INLINE_VARIABLES |
| 146 | + |
| 147 | +#if defined(_CCCL_NO_NOEXCEPT_FUNCTION_TYPE) |
125 | 148 | # define _CCCL_FUNCTION_TYPE_NOEXCEPT |
126 | | -#endif // _CCCL_STD_VER <= 2014 |
| 149 | +#else // ^^^ _CCCL_NO_NOEXCEPT_FUNCTION_TYPE ^^^ / vvv !_CCCL_NO_NOEXCEPT_FUNCTION_TYPE vvv |
| 150 | +# define _CCCL_FUNCTION_TYPE_NOEXCEPT noexcept |
| 151 | +#endif // !_CCCL_NO_NOEXCEPT_FUNCTION_TYPE |
| 152 | + |
| 153 | +#if defined(_CCCL_NO_NONTYPE_TEMPLATE_PARAMETER_AUTO) |
| 154 | +# define _CCCL_NTTP_AUTO unsigned long long int |
| 155 | +#else // ^^^ _CCCL_NO_NONTYPE_TEMPLATE_PARAMETER_AUTO ^^^ / vvv !_CCCL_NO_NONTYPE_TEMPLATE_PARAMETER_AUTO vvv |
| 156 | +# define _CCCL_NTTP_AUTO auto |
| 157 | +#endif // !_CCCL_NO_NONTYPE_TEMPLATE_PARAMETER_AUTO |
127 | 158 |
|
128 | 159 | // Variable templates are more efficient most of the time, so we want to use them rather than structs when possible |
129 | 160 | #if defined(_CCCL_NO_VARIABLE_TEMPLATES) |
|
132 | 163 | # define _CCCL_TRAIT(__TRAIT, ...) __TRAIT##_v<__VA_ARGS__> |
133 | 164 | #endif // !_CCCL_NO_VARIABLE_TEMPLATES |
134 | 165 |
|
| 166 | +// In nvcc prior to 11.3 global variables could not be marked constexpr |
| 167 | +#if _CCCL_CUDACC_BELOW(11, 3) |
| 168 | +# define _CCCL_CONSTEXPR_GLOBAL const |
| 169 | +#else // ^^^ _CCCL_CUDACC_BELOW(11, 3) ^^^ / vvv _CCCL_CUDACC_AT_LEAST(11, 3) vvv |
| 170 | +# define _CCCL_CONSTEXPR_GLOBAL constexpr |
| 171 | +#endif // _CCCL_CUDACC_AT_LEAST(11, 3) |
| 172 | + |
135 | 173 | // We need to treat host and device separately |
136 | 174 | #if defined(__CUDA_ARCH__) |
137 | 175 | # define _CCCL_GLOBAL_CONSTANT _CCCL_DEVICE _CCCL_CONSTEXPR_GLOBAL |
|
0 commit comments