@@ -246,6 +246,38 @@ <h1>Header <experimental/type_traits> synopsis</h1>
246
246
template <class T>
247
247
using raw_invocation_type_t = typename raw_invocation_type<T> ::type;
248
248
249
+ < cxx-ref insynopsis to ="meta.detect "> </ cxx-ref >
250
+ template <class...> using void_t = void;
251
+
252
+ struct nonesuch {
253
+ nonesuch() = delete;
254
+ ~nonesuch() = delete;
255
+ nonesuch(nonesuch const&) = delete;
256
+
257
+ void operator=(nonesuch const&) = delete;
258
+ };
259
+
260
+ template <template<class...> class Op, class... Args>
261
+ using is_detected = < i > see below</ i > ;
262
+ template <template<class...> class Op, class... Args>
263
+ constexpr bool is_detected_v = is_detected<Op, Args...> ::value;
264
+ template <template<class...> class Op, class... Args>
265
+ using detected_t = < i > see below</ i > ;
266
+ template <class Default, template<class...> class Op, class... Args>
267
+ using detected_or = < i > see below</ i > ;
268
+ template <class Default, template<class...> class Op, class... Args>
269
+ using detected_or_t = typename detected_or<Default, Op, Args...> ::type;
270
+ template <class Expected, template<class...> class Op, class... Args>
271
+ using is_detected_exact = is_same<Expected, detected_t<Op, Args...> > ;
272
+ template <class Expected, template<class...> class Op, class... Args>
273
+ constexpr bool is_detected_exact_v
274
+ = is_detected_exact<Expected, Op, Args...> ::value;
275
+ template <class To, template<class...> class Op, class... Args>
276
+ using is_detected_convertible = is_convertible<detected_t<Op, Args...> , To> ;
277
+ template <class To, template<class...> class Op, class... Args>
278
+ constexpr bool is_detected_convertible_v
279
+ = is_detected_convertible<To, Op, Args...> ::value;
280
+
249
281
} // namespace fundamentals_v2
250
282
} // namespace experimental
251
283
} // namespace std</ code > </ pre >
@@ -390,6 +422,57 @@ <h1>Other type transformations</h1>
390
422
</ li >
391
423
</ ul >
392
424
</ cxx-section>
425
+
426
+ < cxx-section id ="meta.detect ">
427
+ < h1 > Detection idiom</ h1 >
428
+
429
+ < pre > < code > template <class Default, class AlwaysVoid,
430
+ template<class...> class Op, class... Args>
431
+ struct DETECTOR { // < i > exposition only</ i >
432
+ using value_t = false_type;
433
+ using type = Default;
434
+ };
435
+
436
+ template <class Default, template<class...> class Op, class... Args>
437
+ struct DETECTOR<Default, void_t<Op<Args...> > , Op, Args...> { // < i > exposition only</ i >
438
+ using value_t = true_type;
439
+ using type = Op<Args...> ;
440
+ };
441
+
442
+ template <template<class...> class Op, class... Args>
443
+ using is_detected = typename DETECTOR<nonesuch, void, Op, Args...> ::value_t;
444
+
445
+ template <template<class...> class Op, class... Args>
446
+ using detected_t = typename DETECTOR<nonesuch, void, Op, Args...> ::type;
447
+
448
+ template <class Default, template<class...> class Op, class... Args>
449
+ using detected_or = DETECTOR<Default, void, Op, Args...> ;</ code > </ pre >
450
+
451
+ < cxx-example >
452
+ < pre > < code > // < i > archetypal helper alias for a copy assignment operation:</ i >
453
+ template <class T>
454
+ using copy_assign_t = decltype(declval<T&> () = declval<T const &> ());
455
+
456
+ // < i > plausible implementation for the is_assignable type trait:</ i >
457
+ template <class T>
458
+ using is_copy_assignable = is_detected<T, copy_assign_t> ;
459
+
460
+ // < i > plausible implementation for an augmented is_assignable type trait</ i >
461
+ // < i > that also checks the return type:</ i >
462
+ template <class T>
463
+ using is_canonical_copy_assignable = is_detected_exact<T&, T, copy_assign_t> ;</ code > </ pre >
464
+ </ cxx-example >
465
+
466
+ < cxx-example >
467
+ < pre > < code > // < i > archetypal helper alias for a particular type member:</ i >
468
+ template <class T>
469
+ using diff_t = typename T::difference_type;
470
+
471
+ // < i > alias the type member, if it exists, otherwise alias </ i > ptrdiff_t< i > :</ i >
472
+ template <class Ptr>
473
+ using difference_type = detected_or_t<ptrdiff_t, diff_t, Ptr> ;</ code > </ pre >
474
+ </ cxx-example >
475
+ </ cxx-section >
393
476
</ cxx-section>
394
477
395
478
< cxx-section id ="ratio ">
0 commit comments