@@ -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 &&) -> 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,6 +206,9 @@ 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 () {
@@ -227,21 +234,21 @@ template <typename T> constexpr auto is_ct_v<T const> = is_ct_v<T>;
227
234
228
235
#ifndef CX_VALUE
229
236
#define CX_VALUE (...) \
230
- []() constexpr { \
237
+ [& ]() constexpr { \
231
238
STDX_PRAGMA (diagnostic push) \
232
239
STDX_PRAGMA (diagnostic ignored " -Wold-style-cast" ) \
233
240
STDX_PRAGMA (diagnostic ignored " -Wunused-value" ) \
234
241
if constexpr (decltype (stdx::cxv_detail::is_type< \
235
242
stdx::cxv_detail::from_any ( \
236
243
__VA_ARGS__)>())::value) { \
237
- return stdx::overload{stdx::cxv_detail::cx_base{}, [] { \
244
+ return stdx::overload{stdx::cxv_detail::cx_base{}, [& ] { \
238
245
return stdx::type_identity< \
239
246
decltype (stdx::cxv_detail::type_of< \
240
247
stdx::cxv_detail::from_any ( \
241
248
__VA_ARGS__)>())>{}; \
242
249
}}; \
243
250
} else { \
244
- return stdx::overload{stdx::cxv_detail::cx_base{}, [] { \
251
+ return stdx::overload{stdx::cxv_detail::cx_base{}, [& ] { \
245
252
return (__VA_ARGS__) + \
246
253
stdx::cxv_detail::type_val{}; \
247
254
}}; \
@@ -265,6 +272,30 @@ template <typename T> constexpr auto is_ct_v<T const> = is_ct_v<T>;
265
272
} \
266
273
}([&] { return X; })
267
274
275
+ #define CX_WRAP (X ) \
276
+ [&]<typename F>(F) { \
277
+ STDX_PRAGMA (diagnostic push) \
278
+ STDX_PRAGMA (diagnostic ignored " -Wold-style-cast" ) \
279
+ 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
+ (X) + \
285
+ ::stdx::cxv_detail::type_val{})>; \
286
+ }) { \
287
+ return CX_VALUE (X); \
288
+ } else { \
289
+ return (X) + ::stdx::cxv_detail::type_val{}; \
290
+ } \
291
+ STDX_PRAGMA (diagnostic pop) \
292
+ }([&] { \
293
+ STDX_PRAGMA (diagnostic push) \
294
+ STDX_PRAGMA (diagnostic ignored " -Wold-style-cast" ) \
295
+ return (X) + stdx::cxv_detail::type_val{}; \
296
+ STDX_PRAGMA (diagnostic pop) \
297
+ })
298
+
268
299
#endif
269
300
270
301
// NOLINTEND(cppcoreguidelines-macro-usage)
0 commit comments