Skip to content

Commit 8d5072c

Browse files
committed
🎨 Simplify type_of
Problem: - The `CX_WRAP` and `CX_VALUE` macros jump through hoops to retrieve the type (when a type is passed in). It's simpler to use `__typeof__`. Solution: - Replace `type_of` and `typer` constructs with `__typeof__`.
1 parent 0b7d737 commit 8d5072c

File tree

1 file changed

+18
-28
lines changed

1 file changed

+18
-28
lines changed

include/stdx/utility.hpp

Lines changed: 18 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -163,20 +163,8 @@ struct type_val {
163163
}
164164
};
165165

166-
template <typename>
167-
constexpr inline auto is_type = [] { return std::true_type{}; };
168-
template <>
169-
constexpr inline auto is_type<from_any> = [] { return std::false_type{}; };
170-
171-
template <typename> struct typer {
172-
using type = void;
173-
};
174-
template <typename T> struct typer<from_any(T)> {
175-
using type = T;
176-
};
177-
178-
template <int> constexpr auto type_of() -> void;
179-
template <typename T> constexpr auto type_of() -> typename typer<T>::type;
166+
template <typename> constexpr inline auto is_type = true;
167+
template <> constexpr inline auto is_type<from_any> = false;
180168

181169
class cx_base {
182170
struct unusable {};
@@ -236,21 +224,22 @@ template <typename T> constexpr auto is_ct_v<T const> = is_ct_v<T>;
236224
#define FWD(x) std::forward<decltype(x)>(x)
237225
#endif
238226

227+
#ifndef STDX_IS_TYPE
228+
#define STDX_IS_TYPE(...) \
229+
::stdx::cxv_detail::is_type<__typeof__(::stdx::cxv_detail::from_any( \
230+
__VA_ARGS__))>
231+
#endif
232+
239233
#ifndef CX_VALUE
240234
#define CX_VALUE(...) \
241235
[]() constexpr { \
242236
STDX_PRAGMA(diagnostic push) \
243237
STDX_PRAGMA(diagnostic ignored "-Wold-style-cast") \
244238
STDX_PRAGMA(diagnostic ignored "-Wunused-value") \
245-
if constexpr (decltype(::stdx::cxv_detail::is_type< \
246-
__typeof__(::stdx::cxv_detail::from_any( \
247-
__VA_ARGS__))>())::value) { \
239+
if constexpr (STDX_IS_TYPE(__VA_ARGS__)) { \
248240
return ::stdx::overload{ \
249241
::stdx::cxv_detail::cx_base{}, [] { \
250-
return ::stdx::type_identity< \
251-
decltype(::stdx::cxv_detail::type_of< \
252-
::stdx::cxv_detail::from_any( \
253-
__VA_ARGS__)>())>{}; \
242+
return ::stdx::type_identity<__typeof__(__VA_ARGS__)>{}; \
254243
}}; \
255244
} else { \
256245
return ::stdx::overload{::stdx::cxv_detail::cx_base{}, [] { \
@@ -264,6 +253,7 @@ template <typename T> constexpr auto is_ct_v<T const> = is_ct_v<T>;
264253

265254
#if __cplusplus >= 202002L
266255

256+
#ifndef CT_WRAP
267257
#define CT_WRAP(...) \
268258
[&](auto f) { \
269259
if constexpr (::stdx::is_ct_v<decltype(f())>) { \
@@ -278,7 +268,9 @@ template <typename T> constexpr auto is_ct_v<T const> = is_ct_v<T>;
278268
return f(); \
279269
} \
280270
}([&] { return __VA_ARGS__; })
271+
#endif
281272

273+
#ifndef CX_DETECT
282274
#ifdef __clang__
283275
#define CX_DETECT(...) \
284276
std::is_empty_v<decltype([&] { \
@@ -297,20 +289,17 @@ constexpr auto cx_detect1(auto) { return 0; }
297289
(__VA_ARGS__) + ::stdx::cxv_detail::type_val{})>; \
298290
}
299291
#endif
292+
#endif
300293

294+
#ifndef CX_WRAP
301295
#define CX_WRAP(...) \
302296
[&]([[maybe_unused]] auto f) { \
303297
STDX_PRAGMA(diagnostic push) \
304298
STDX_PRAGMA(diagnostic ignored "-Wold-style-cast") \
305-
if constexpr (decltype(::stdx::cxv_detail::is_type< \
306-
__typeof__(::stdx::cxv_detail::from_any( \
307-
__VA_ARGS__))>())::value) { \
299+
if constexpr (STDX_IS_TYPE(__VA_ARGS__)) { \
308300
return ::stdx::overload{ \
309301
::stdx::cxv_detail::cx_base{}, [&] { \
310-
return ::stdx::type_identity< \
311-
typename ::stdx::cxv_detail::typer< \
312-
__typeof__(::stdx::cxv_detail::from_any( \
313-
__VA_ARGS__))>::type>{}; \
302+
return ::stdx::type_identity<__typeof__(__VA_ARGS__)>{}; \
314303
}}; \
315304
} else if constexpr (::stdx::is_cx_value_v< \
316305
std::invoke_result_t<decltype(f)>> or \
@@ -331,6 +320,7 @@ constexpr auto cx_detect1(auto) { return 0; }
331320
})
332321

333322
#endif
323+
#endif
334324

335325
// NOLINTEND(cppcoreguidelines-macro-usage)
336326
// NOLINTEND(modernize-use-constraints)

0 commit comments

Comments
 (0)