Skip to content

Commit 73e1d48

Browse files
authored
Merge pull request #255 from elbeno/simplify-type-of
🎨 Simplify `type_of`
2 parents 0b7d737 + ff3c418 commit 73e1d48

File tree

2 files changed

+20
-35
lines changed

2 files changed

+20
-35
lines changed

include/stdx/utility.hpp

Lines changed: 18 additions & 31 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,21 +289,15 @@ 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) { \
308-
return ::stdx::overload{ \
309-
::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>{}; \
314-
}}; \
299+
if constexpr (STDX_IS_TYPE(__VA_ARGS__)) { \
300+
return ::stdx::type_identity<__typeof__(__VA_ARGS__)>{}; \
315301
} else if constexpr (::stdx::is_cx_value_v< \
316302
std::invoke_result_t<decltype(f)>> or \
317303
std::is_empty_v< \
@@ -331,6 +317,7 @@ constexpr auto cx_detect1(auto) { return 0; }
331317
})
332318

333319
#endif
320+
#endif
334321

335322
// NOLINTEND(cppcoreguidelines-macro-usage)
336323
// NOLINTEND(modernize-use-constraints)

test/utility.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -359,16 +359,14 @@ TEST_CASE("CX_WRAP template argument", "[utility]") {
359359
}
360360

361361
TEST_CASE("CX_WRAP type argument", "[utility]") {
362-
STATIC_REQUIRE(stdx::is_cx_value_v<decltype(CX_WRAP(int))>);
363362
STATIC_REQUIRE(
364-
std::is_same_v<decltype(CX_WRAP(int)()), stdx::type_identity<int>>);
363+
std::is_same_v<decltype(CX_WRAP(int)), stdx::type_identity<int>>);
365364
}
366365

367366
TEST_CASE("CX_WRAP empty type argument", "[utility]") {
368367
using X = std::integral_constant<int, 17>;
369-
STATIC_REQUIRE(stdx::is_cx_value_v<decltype(CX_WRAP(X))>);
370368
STATIC_REQUIRE(
371-
std::is_same_v<decltype(CX_WRAP(X)()), stdx::type_identity<X>>);
369+
std::is_same_v<decltype(CX_WRAP(X)), stdx::type_identity<X>>);
372370
}
373371

374372
TEST_CASE("CX_WRAP integral_constant arg", "[utility]") {

0 commit comments

Comments
 (0)