@@ -148,7 +148,7 @@ 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; }
@@ -238,20 +238,21 @@ template <typename T> constexpr auto is_ct_v<T const> = is_ct_v<T>;
238
238
STDX_PRAGMA (diagnostic push) \
239
239
STDX_PRAGMA (diagnostic ignored " -Wold-style-cast" ) \
240
240
STDX_PRAGMA (diagnostic ignored " -Wunused-value" ) \
241
- if constexpr (decltype (stdx::cxv_detail::is_type< \
242
- stdx::cxv_detail::from_any ( \
241
+ if constexpr (decltype (:: stdx::cxv_detail::is_type< \
242
+ :: stdx::cxv_detail::from_any ( \
243
243
__VA_ARGS__)>())::value) { \
244
- return stdx::overload{stdx::cxv_detail::cx_base{}, [&] { \
245
- return stdx::type_identity< \
246
- decltype (stdx::cxv_detail::type_of< \
247
- stdx::cxv_detail::from_any ( \
248
- __VA_ARGS__)>())>{}; \
249
- }}; \
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
+ }}; \
250
251
} else { \
251
- return stdx::overload{stdx::cxv_detail::cx_base{}, [&] { \
252
- return (__VA_ARGS__) + \
253
- stdx::cxv_detail::type_val{}; \
254
- }}; \
252
+ return :: stdx::overload{:: stdx::cxv_detail::cx_base{}, [&] { \
253
+ return (__VA_ARGS__) + \
254
+ :: stdx::cxv_detail::type_val{}; \
255
+ }}; \
255
256
} \
256
257
STDX_PRAGMA (diagnostic pop) \
257
258
}()
@@ -272,26 +273,49 @@ template <typename T> constexpr auto is_ct_v<T const> = is_ct_v<T>;
272
273
} \
273
274
}([&] { return X; })
274
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
+
275
292
#define CX_WRAP (X ) \
276
- [&]<typename F>(F) { \
293
+ [&]<typename F>(F f ) { \
277
294
STDX_PRAGMA (diagnostic push) \
278
295
STDX_PRAGMA (diagnostic ignored " -Wold-style-cast" ) \
279
296
if constexpr (::stdx::is_cx_value_v<std::invoke_result_t <F>>) { \
280
- return (X) + ::stdx::cxv_detail::type_val{}; \
281
- } else if constexpr (requires { \
282
- ::stdx::detail::cx_detect0< \
283
- ::stdx::detail::cx_detect1 ( \
284
- CX_VALUE (X)())>; \
285
- }) { \
286
- return CX_VALUE (X); \
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
+ } \
287
311
} else { \
288
- return (X) + ::stdx::cxv_detail::type_val{}; \
312
+ return f (); \
289
313
} \
290
314
STDX_PRAGMA (diagnostic pop) \
291
315
}([&] { \
292
316
STDX_PRAGMA (diagnostic push) \
293
317
STDX_PRAGMA (diagnostic ignored " -Wold-style-cast" ) \
294
- return (X) + stdx::cxv_detail::type_val{}; \
318
+ return (X) + :: stdx::cxv_detail::type_val{}; \
295
319
STDX_PRAGMA (diagnostic pop) \
296
320
})
297
321
0 commit comments