MeVisLab Toolbox Reference
mlTemplateHelpers.h
Go to the documentation of this file.
1 /*************************************************************************************
2 **
3 ** Copyright 2021, MeVis Medical Solutions AG
4 **
5 ** The user may use this file in accordance with the license agreement provided with
6 ** the Software or, alternatively, in accordance with the terms contained in a
7 ** written agreement between the user and MeVis Medical Solutions AG.
8 **
9 ** For further information use the contact form at https://www.mevislab.de/contact
10 **
11 **************************************************************************************/
12 
13 #pragma once
14 
15 #include "mlTypeDefs.h"
16 
17 ML_START_NAMESPACE
18 
19 /*
20  * Utility template for easier use within std::visit.
21  * See https://en.cppreference.com/w/cpp/utility/variant/visit
22  */
23 template <class... Ts> struct Overload : Ts...
24 {
25  using Ts::operator()...;
26 };
27 template <class... Ts> Overload(Ts...)->Overload<Ts...>;
28 
30 //
31 // the following implements the C++ standard 17 proposal N4502
32 // For further information see https://en.cppreference.com/w/cpp/experimental/is_detected
34 
35 namespace internal
36 {
37 
38 #if __GNUC__ < 5 && !defined __clang__
39  // http://stackoverflow.com/a/28967049/1353549
40  template <typename...>
41  struct voider {
42  using type = void;
43  };
44  template <typename... Ts>
45  using void_t = typename voider<Ts...>::type;
46 #else
47  template <typename...>
48  using void_t = void;
49 #endif
50 
51  struct nonesuch {
52  nonesuch() = delete;
53  ~nonesuch() = delete;
54  nonesuch(nonesuch const&) = delete;
55  void operator=(nonesuch const&) = delete;
56  };
57 
58  // primary template handles all types not supporting the archetypal Op:
59  template <class Default, class, template <class...> class Op, class... Args>
60  struct detector {
61  using value_t = std::false_type;
62  using type = Default;
63  };
64 
65  // the specialization recognizes and handles only types supporting Op:
66  template <class Default, template <class...> class Op, class... Args>
67  struct detector<Default, void_t<Op<Args...>>, Op, Args...> {
68  using value_t = std::true_type;
69  using type = Op<Args...>;
70  };
71 }
72 
73 template <template <class...> class Op, class... Args>
74 using is_detected = typename internal::detector<internal::nonesuch, void, Op, Args...>::value_t;
75 
76 template <template <class...> class Op, class... Args>
77 constexpr bool is_detected_v = is_detected<Op, Args...>::value;
78 
79 template <template <class...> class Op, class... Args>
80 using detected_t = typename internal::detector<internal::nonesuch, void, Op, Args...>::type;
81 
82 
83 
84 ML_END_NAMESPACE
typename voider< Ts... >::type void_t
typename internal::detector< internal::nonesuch, void, Op, Args... >::type detected_t
constexpr bool is_detected_v
typename internal::detector< internal::nonesuch, void, Op, Args... >::value_t is_detected
Overload(Ts...) -> Overload< Ts... >
void operator=(nonesuch const &)=delete
nonesuch(nonesuch const &)=delete