CsCrypto  1.0.1
is_detected_traits.h
1 /***********************************************************************
2 *
3 * Copyright (c) 2021-2024 Tim van Deurzen
4 * Copyright (c) 2021-2024 Barbara Geller
5 * Copyright (c) 2021-2024 Ansel Sermersheim
6 *
7 * This file is part of CsCrypto.
8 *
9 * CsCrypto is free software, released under the BSD 2-Clause license.
10 * For license details refer to LICENSE provided with this project.
11 *
12 * CsCrypto is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15 *
16 * https://opensource.org/licenses/BSD-2-Clause
17 *
18 ***********************************************************************/
19 
20 /***********************************************************************
21 *
22 * Experimental implementation derived from
23 * https://en.cppreference.com/w/cpp/experimental/is_detected
24 *
25 ***********************************************************************/
26 
27 #ifndef CS_CRYPTO_UTIL_IS_DETECTED_TRAITS_H
28 #define CS_CRYPTO_UTIL_IS_DETECTED_TRAITS_H
29 
30 #include <type_traits>
31 
32 namespace cs_crypto::traits {
33 
34 struct nonesuch
35 {
36  nonesuch() = delete;
37 
38  nonesuch(const nonesuch &) = delete;
39  nonesuch(nonesuch &&) = delete;
40 
41  ~nonesuch() = delete;
42 
43  void operator=(const nonesuch &) = delete;
44  void operator=(nonesuch &&) = delete;
45 };
46 
47 template<class Default, class AlwaysVoid, template<class...> class Op, class... Args>
48 struct detector
49 {
50  using value_t = std::false_type;
51  using type = Default;
52 };
53 
54 template<class Default, template<class...> class Op, class... Args>
55 struct detector<Default, std::void_t<Op<Args...>>, Op, Args...>
56 {
57  using value_t = std::true_type;
58  using type = Op<Args...>;
59 };
60 
61 template<template<class...> class Op, class... Args>
62 using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
63 
64 template<template<class...> class Op, class... Args>
65 using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
66 
67 template<template<class...> class Op, class... Args>
68 constexpr bool is_detected_v = is_detected<Op, Args...>::value;
69 
70 template<class Default, template<class...> class Op, class... Args>
71 using detected_or = detector<Default, void, Op, Args...>;
72 
73 template<class Default, template<class...> class Op, class... Args>
74 using detected_or_t = typename detected_or<Default, Op, Args...>::type;
75 
76 } // namespace cs_crypto::traits
77 
78 #endif