SUNphi
1.0
Main Page
Related Pages
Namespaces
Classes
Files
File List
File Members
SFINAE.hpp
Go to the documentation of this file.
1
#
ifndef
_SFINAE_HPP
2
#
define
_SFINAE_HPP
3
4
/// \file SFINAE.hpp
5
///
6
/// \brief Defines macros to enable or disable template instantiation
7
///
8
/// http://en.cppreference.com/w/cpp/language/sfinae
9
10
#
include
<
metaprogramming
/
TypeTraits
.
hpp
>
11
12
namespace
SUNphi
13
{
14
/// Provides a SFINAE to be used in template par list
15
///
16
/// This follows
17
/// https://stackoverflow.com/questions/32636275/sfinae-with-variadic-templates
18
/// as in this example
19
/// \code
20
/// template <typename D,
21
/// SFINAE_ON_TEMPLATE_ARG(IsSame<D,int>)>
22
/// void foo(D i) {} // fails if D is not int
23
/// \endcode
24
#
define
SFINAE_ON_TEMPLATE_ARG
(
...
)
25
TypeIf
<
(
__VA_ARGS__
)
,
void
*
>
=
nullptr
26
27
/// Provides template par list to unprioritize default SFINAE
28
///
29
/// Use as last argument of a function overloaded by a other
30
/// implementations using SFINAE to detect the proper version to be
31
/// used. This has to be used in conjunction with the other macros
32
/// SFINAE_WORSEN_DEFAULT_VERSION_ARGS and
33
/// SFINAE_WORSEN_DEFAULT_VERSION_ARGS_CHECK as in this example
34
///
35
/// \code
36
/// template <typename T,
37
/// SFINAE_WORSEN_DEFAULT_VERSION_TEMPLATE_PARS>
38
/// int tell(T a,SFINAE_WORSEN_DEFAULT_VERSION_ARGS)
39
/// {
40
/// SFINAE_WORSEN_DEFAULT_VERSION_ARGS_CHECK;
41
/// return 1;
42
/// }
43
///
44
/// template <typename T,
45
/// std::enable_if_t<sizeof(T)==4,void*> =nullptr>
46
/// decltype(auto) tell(T&& a)
47
/// {
48
/// return a+1;
49
/// }
50
///
51
/// int main()
52
/// {
53
/// tell(1); //returns 2
54
///
55
/// return 0;
56
/// }
57
///\endcode
58
#
define
SFINAE_WORSEN_DEFAULT_VERSION_TEMPLATE_PARS
59
typename
...
DummyTypes
/* Fake list of types */
60
61
/// Provide empty list of args, used to unprioritize default version
62
#
define
SFINAE_WORSEN_DEFAULT_VERSION_ARGS
63
DummyTypes
...
/*< Fake list of args */
64
65
/// Check that no extra arg is passed
66
#
define
SFINAE_WORSEN_DEFAULT_VERSION_ARGS_CHECK
67
STATIC_ASSERT_ARE_N_TYPES
(
0
,
DummyTypes
)
68
69
//////////////////////////////////////////////////////////////////////
70
71
/// SFINAE for template class specialisation
72
///
73
/// Mechanism to allow the usage of SFINAE to allow a class specialization.
74
/// Follows the advice of https://stackoverflow.com/a/30991097 to
75
/// create a class providing the type itself
76
///
77
/// Example:
78
///
79
/// \code
80
///
81
/// Class which needs to be explicitly specialized with SFINAE
82
/// template <typename T>
83
/// class SpecializableClass
84
/// {
85
/// };
86
///
87
/// /// Dummy type to be used to specialize the class
88
/// class SpecializingArg
89
/// {
90
/// };
91
///
92
/// PROVIDE_ENABLE_IF_FOR_TYPE(SpecializingArg);
93
///
94
/// /// Specializes the class SpecializableClass
95
/// SFINAE_TEMPLATE_CLASS_SPECIALIZATION_PREAMBLE
96
/// class SpecializableClass<SFINAE_TEMPLATE_CLASS_SPECIALIZATION_ARG(SpecializingArg)>
97
/// {
98
/// SFINAE_TEMPLATE_CLASS_SPECIALIZATION_PROVIDE_TYPE;
99
///
100
/// /// To show explicit usage of T
101
/// SpecializableClass<T>()
102
/// {
103
/// }
104
/// };
105
///
106
/// \endcode
107
///
108
#
define
SFINAE_TEMPLATE_CLASS_SPECIALIZATION_PREAMBLE
109
template
<
template
<
typename
...
>
typename
TT
,
110
typename
...
Ts
>
111
112
/// To be used as an argument of the specialization
113
#
define
SFINAE_TEMPLATE_CLASS_SPECIALIZATION_ARG
(
TYPE
)
114
EnableIfIs
##
TYPE
<
TT
<
Ts
...
>
,
TT
<
Ts
...
>>
115
116
/// Provides the type inside the specialized class
117
#
define
SFINAE_TEMPLATE_CLASS_SPECIALIZATION_PROVIDE_TYPE
118
/*! Type used as an argument of the template specialization */
119
using
T
=
120
TT
<
Ts
...
>
121
}
122
123
#
endif
STATIC_ASSERT_ARE_N_TYPES
#define STATIC_ASSERT_ARE_N_TYPES(N, UNEXP_PARPACK)
Static assert if not passing exactly N types.
Definition:
TypeTraits.hpp:422
include
metaprogramming
SFINAE.hpp
Generated by
1.8.11