@@ -148,14 +148,18 @@ struct from_any {
148
148
struct type_val {
149
149
template <typename T, typename U,
150
150
typename = std::enable_if_t <same_as_unqualified<type_val, U>>>
151
- friend constexpr auto operator +(T && t, U & &) -> T {
151
+ friend constexpr auto operator +(T t, U const &) -> T {
152
152
return t;
153
153
}
154
154
friend constexpr auto operator +(type_val const &f) -> type_val { return f; }
155
155
// NOLINTNEXTLINE(google-explicit-constructor)
156
156
template <typename T> constexpr operator T () const {
157
- extern auto cxv_type_val_get_t (T *) -> T;
158
- return cxv_type_val_get_t (nullptr );
157
+ if constexpr (std::is_default_constructible_v<T>) {
158
+ return T{};
159
+ } else {
160
+ extern auto cxv_type_val_get_t (T *) -> T;
161
+ return cxv_type_val_get_t (nullptr );
162
+ }
159
163
}
160
164
};
161
165
@@ -202,13 +206,22 @@ template <typename T> struct ct_helper {
202
206
T value;
203
207
};
204
208
template <typename T> ct_helper (T) -> ct_helper<T>;
209
+
210
+ template <auto > CONSTEVAL auto cx_detect0 () {}
211
+ CONSTEVAL auto cx_detect1 (auto ) { return 0 ; }
205
212
} // namespace detail
206
213
207
214
template <detail::ct_helper Value> CONSTEVAL auto ct () {
208
215
return std::integral_constant<decltype (Value.value ), Value.value >{};
209
216
}
210
217
template <typename T> CONSTEVAL auto ct () { return type_identity<T>{}; }
211
218
219
+ template <typename > constexpr auto is_ct_v = false ;
220
+ template <typename T, T V>
221
+ constexpr auto is_ct_v<std::integral_constant<T, V>> = true ;
222
+ template <typename T> constexpr auto is_ct_v<type_identity<T>> = true ;
223
+ template <typename T> constexpr auto is_ct_v<T const > = is_ct_v<T>;
224
+
212
225
#endif
213
226
} // namespace v1
214
227
} // namespace stdx
@@ -221,28 +234,92 @@ template <typename T> CONSTEVAL auto ct() { return type_identity<T>{}; }
221
234
222
235
#ifndef CX_VALUE
223
236
#define CX_VALUE (...) \
224
- []() constexpr { \
237
+ [& ]() constexpr { \
225
238
STDX_PRAGMA (diagnostic push) \
226
239
STDX_PRAGMA (diagnostic ignored " -Wold-style-cast" ) \
227
240
STDX_PRAGMA (diagnostic ignored " -Wunused-value" ) \
228
- if constexpr (decltype (stdx::cxv_detail::is_type< \
229
- stdx::cxv_detail::from_any ( \
241
+ if constexpr (decltype (:: stdx::cxv_detail::is_type< \
242
+ :: stdx::cxv_detail::from_any ( \
230
243
__VA_ARGS__)>())::value) { \
231
- return stdx::overload{stdx::cxv_detail::cx_base{}, [] { \
232
- return stdx::type_identity< \
233
- decltype (stdx::cxv_detail::type_of< \
234
- stdx::cxv_detail::from_any ( \
235
- __VA_ARGS__)>())>{}; \
236
- }}; \
244
+ return ::stdx::overload{ \
245
+ ::stdx::cxv_detail::cx_base{}, [&] { \
246
+ return ::stdx::type_identity< \
247
+ decltype (::stdx::cxv_detail::type_of< \
248
+ ::stdx::cxv_detail::from_any ( \
249
+ __VA_ARGS__)>())>{}; \
250
+ }}; \
237
251
} else { \
238
- return stdx::overload{stdx::cxv_detail::cx_base{}, [] { \
239
- return (__VA_ARGS__) + \
240
- stdx::cxv_detail::type_val{}; \
241
- }}; \
252
+ return :: stdx::overload{:: stdx::cxv_detail::cx_base{}, [& ] { \
253
+ return (__VA_ARGS__) + \
254
+ :: stdx::cxv_detail::type_val{}; \
255
+ }}; \
242
256
} \
243
257
STDX_PRAGMA (diagnostic pop) \
244
258
}()
245
259
#endif
246
260
261
+ #if __cplusplus >= 202002L
262
+
263
+ #define CT_WRAP (X ) \
264
+ [&](auto f) { \
265
+ if constexpr (::stdx::is_ct_v<decltype (f ())>) { \
266
+ return f (); \
267
+ } else if constexpr (requires { \
268
+ ::stdx::ct<[&]() constexpr { return X; }()>; \
269
+ }) { \
270
+ return ::stdx::ct<[&]() constexpr { return X; }()>(); \
271
+ } else { \
272
+ return f (); \
273
+ } \
274
+ }([&] { return X; })
275
+
276
+ #ifdef __clang__
277
+ #define CX_DETECT (X ) std::is_empty_v<decltype (CX_VALUE(X))>
278
+ #else
279
+ namespace stdx {
280
+ inline namespace v1 {
281
+ template <auto > constexpr auto cx_detect0 () {}
282
+ constexpr auto cx_detect1 (auto ) { return 0 ; }
283
+ } // namespace v1
284
+ } // namespace stdx
285
+ #define CX_DETECT (X ) \
286
+ requires { \
287
+ ::stdx::cx_detect0<::stdx::cx_detect1 ( \
288
+ (X) + ::stdx::cxv_detail::type_val{})>; \
289
+ }
290
+ #endif
291
+
292
+ #define CX_WRAP (X ) \
293
+ [&]<typename F>(F f) { \
294
+ STDX_PRAGMA (diagnostic push) \
295
+ STDX_PRAGMA (diagnostic ignored " -Wold-style-cast" ) \
296
+ if constexpr (::stdx::is_cx_value_v<std::invoke_result_t <F>>) { \
297
+ return f (); \
298
+ } else if constexpr (CX_DETECT (X)) { \
299
+ if constexpr (decltype (::stdx::cxv_detail::is_type< \
300
+ ::stdx::cxv_detail::from_any ( \
301
+ X)>())::value) { \
302
+ return ::stdx::overload{ \
303
+ ::stdx::cxv_detail::cx_base{}, [&] { \
304
+ return ::stdx::type_identity< \
305
+ decltype (::stdx::cxv_detail::type_of< \
306
+ ::stdx::cxv_detail::from_any (X)>())>{}; \
307
+ }}; \
308
+ } else { \
309
+ return ::stdx::overload{::stdx::cxv_detail::cx_base{}, f}; \
310
+ } \
311
+ } else { \
312
+ return f (); \
313
+ } \
314
+ STDX_PRAGMA (diagnostic pop) \
315
+ }([&] { \
316
+ STDX_PRAGMA (diagnostic push) \
317
+ STDX_PRAGMA (diagnostic ignored " -Wold-style-cast" ) \
318
+ return (X) + ::stdx::cxv_detail::type_val{}; \
319
+ STDX_PRAGMA (diagnostic pop) \
320
+ })
321
+
322
+ #endif
323
+
247
324
// NOLINTEND(cppcoreguidelines-macro-usage)
248
325
// NOLINTEND(modernize-use-constraints)
0 commit comments