SUNphi
1.0
Main Page
Related Pages
Namespaces
Classes
Files
File List
File Members
UnarySmET.hpp
Go to the documentation of this file.
1
#
ifndef
_UNARYSMET_HPP
2
#
define
_UNARYSMET_HPP
3
4
/// \file UnarySmET.hpp
5
///
6
/// \brief Header file defining basic properties of Unary SmET
7
8
#
include
<
iostream
>
9
10
#
include
<
metaprogramming
/
SFINAE
.
hpp
>
11
#
include
<
smet
/
BaseSmET
.
hpp
>
12
#
include
<
smet
/
Reference
.
hpp
>
13
14
#
if
0
15
namespace
SUNphi
16
{
17
/// Defines the UnarySmET type traits
18
DEFINE_BASE_TYPE(UnarySmET,:
public
BaseSmET);
19
20
// Defines the check for a member type "ref"
21
DEFINE_HAS_MEMBER(ref);
22
23
/// Defines the check for a Unary SmET
24
#
define
STATIC_ASSERT_IS_UNARY_SMET
(
...
)
25
STATIC_ASSERT_IS_SMET
(
__VA_ARGS__
)
;
26
STATIC_ASSERT_HAS_MEMBER
(
ref
,
__VA_ARGS__
)
27
28
/// Unary SmET
29
template
<
typename
T>
30
struct
UnarySmET :
31
public
SmET<T>,
32
public
BaseUnarySmET
33
{
34
PROVIDE_CRTP_CAST_OPERATOR(T);
35
};
36
37
/// Provide the reference to the object
38
#
define
PROVIDE_UNARY_SMET_REF
39
PROVIDE_SMET_REF
(
)
40
41
/// Declare that the fundamental type is the same of the reference
42
#
define
SAME_FUND_TYPE_OF_REF
43
/*! Same fundamental type of the reference */
44
using
Fund
=
45
typename
RemRef
<
decltype
(
ref
)
>
::
Fund
46
47
/////////////////////////////////////////////////////////////////
48
49
/// Set the assignability according to the reference
50
#
define
ASSIGNABLE_ACCORDING_TO_REF
51
IS_ASSIGNABLE_ATTRIBUTE
(
/*! This SmET can be assigned if the reference can */
,
RemRef
<
decltype
(
ref
)
>
::
isAssignable
)
52
53
/////////////////////////////////////////////////////////////////
54
55
/// Set the mergeable components equal to the reference
56
#
define
MERGEABLE_ACCORDING_TO_REF
57
PROVIDE_MERGEABLE_COMPS
(
/*! The components of this SmET can be merged as the reference one */
,
typename
RemRef
<
decltype
(
ref
)
>
::
MergeableComps
)
58
59
/// Returns a version of the SmET with simple merging structure
60
#
define
PROVIDE_UNARY_SMET_SIMPLE_GET_MERGED_COMPS_VIEW
(
UNARY_SMET
)
/* Name of the SmET type */
61
PROVIDE_GET_MERGED_COMPS_VIEW
(
/*! Returns a component-merged version */
,
62
auto
refMerged
=
ref
.
template
mergedComps
<
Is
>
(
)
;
63
return
UNARY_SMET
<
decltype
(
refMerged
)
>
(
std
::
move
(
refMerged
)
)
)
64
65
/////////////////////////////////////////////////////////////////
66
67
/// Set the size of components according to the reference
68
#
define
SAME_COMP_SIZES_OF_REF
69
/*! Returns the size of a component, matching the reference */
70
template
<
typename
TC
,
71
SFINAE_WORSEN_DEFAULT_VERSION_TEMPLATE_PARS
>
72
int
compSize
(
SFINAE_WORSEN_DEFAULT_VERSION_ARGS
)
const
73
{
74
SFINAE_WORSEN_DEFAULT_VERSION_ARGS_CHECK
;
75
76
return
77
ref
.
template
compSize
<
TC
>
(
)
;
78
}
79
80
/// Set the size of a specific component
81
#
define
PROVIDE_COMP_SIZES_FOR
(
TC
,
...
)
82
/*! Returns the size of component TC */
83
template
<
typename
T
,
84
SFINAE_ON_TEMPLATE_ARG
(
isSame
<
T
,
TC
>
)
>
85
int
compSize
(
)
const
86
{
87
__VA_ARGS__
;
88
}
89
90
/////////////////////////////////////////////////////////////////
91
92
/// Defines a simple creator taking a reference
93
#
define
PROVIDE_UNARY_SMET_SIMPLE_CREATOR
(
UNARY_SMET
/*!< Name of the UnarySmET */
)
94
/*! Constructor taking universal reference */
95
template
<
typename
Oth
,
96
typename
=
EnableIf
<
isSame
<
Unqualified
<
Oth
>
,
Unqualified
<
Ref
>>
>>
97
explicit
UNARY_SMET
(
Oth
&&
oth
)
:
ref
(
forw
<
Oth
>
(
oth
)
)
98
{
99
}
100
101
/// Defines the assignement operator, calling assign
102
#
define
PROVIDE_UNARY_SMET_ASSIGNEMENT_OPERATOR
(
UNARY_SMET
/*!< Name of the UnarySmET */
)
103
/*! Assign from another object */
104
template
<
typename
Oth
>
/* Other type */
105
UNARY_SMET
&
operator
=
(
Oth
&&
oth
)
/*!< Other object */
106
{
107
if
(
0
)
108
{
109
using
namespace
std
;
110
cout
<<
"Operator=, triggering assignement to "
<<
this
<<
" of "
<<
&
oth
<<
endl
;
111
}
112
assign
(
*
this
,
forw
<
Oth
>
(
oth
)
)
;
113
114
return
115
*
this
;
116
}
117
118
/////////////////////////////////////////////////////////////////
119
120
/// Set aliasing according to the isAliasing of reference
121
///
122
/// \todo enforce cehck only with TensClass, or with storing classes
123
#
define
FORWARD_IS_ALIASING_TO_REF
124
PROVIDE_IS_ALIASING
(
/*! Forward aliasing check to the reference */
,
125
return
ref
.
isAliasing
(
alias
)
;
)
126
127
/// Create a simple builder with a name and a UNARY_SMET returned type
128
#
define
SIMPLE_UNARY_SMET_BUILDER
(
BUILDER
,
/*!< Name of builder fun */
129
UNARY_SMET
)
/*!< Name of the UnarySmET to build */
130
/*! Simple UNARY_SMET builder called BUILDER */
131
/*! */
132
/*! Plain UNARY_SMET getting a plain SmET */
133
template
<
typename
T
,
/* Type of the SmET to get */
134
SFINAE_WORSEN_DEFAULT_VERSION_TEMPLATE_PARS
>
135
UNARY_SMET
<
T
>
BUILDER
(
T
&&
smet
,
/*!< SmET to act upon */
136
SFINAE_WORSEN_DEFAULT_VERSION_ARGS
)
137
{
138
SFINAE_WORSEN_DEFAULT_VERSION_ARGS_CHECK
;
139
140
if
constexpr
(
0
)
141
{
142
using
namespace
std
;
143
constexpr
bool
IsLvalue
=
isLvalue
<
T
>
;
144
constexpr
bool
IsConst
=
isConst
<
T
>
;
145
cout
<<
"Building "
#
UNARY_SMET
" through "
#
BUILDER
<<
endl
;
146
constexpr
bool
Is
=
std
::
is_reference
<
T
>
::
value
;
147
cout
<<
" IsLvalue: "
<<
IsLvalue
<<
", Is: "
<<
Is
<<
", IsConst: "
<<
IsConst
<<
endl
;
148
}
149
return
UNARY_SMET
<
T
>
(
forw
<
T
>
(
smet
)
)
;
150
}
151
SWALLOW_SEMICOLON_AT_GLOBAL_SCOPE
152
153
/// Provides const or non-const evaluator
154
#
define
PROVIDE_UNARY_SMET_CONST_OR_NOT_DEFAULT_EVALUATOR
(
QUALIFIER
)
/*!< Const or not */
155
/*! QUALIFIER Evaluator */
156
/*! \todo add/check that const qualifier is properly added to output */
157
template
<
typename
...
Args
>
158
DECLAUTO
eval
(
const
Args
&
...
args
)
/*!< Parameters to pass */
159
QUALIFIER
160
{
161
STATIC_ASSERT_ARE_N_TYPES
(
TK
::
nTypes
,
args
)
;
162
163
return
164
ref
.
eval
(
forw
<
const
Args
>
(
args
)
...
)
;
165
}
166
167
/// Provides both const and non-const evaluators
168
#
define
PROVIDE_UNARY_SMET_DEFAULT_EVALUATOR
169
PROVIDE_UNARY_SMET_CONST_OR_NOT_DEFAULT_EVALUATOR
(
NON_CONST_QUALIF
)
;
170
PROVIDE_UNARY_SMET_CONST_OR_NOT_DEFAULT_EVALUATOR
(
CONST_QUALIF
)
171
172
/// Implements a duplicated-call canceller
173
///
174
/// Example
175
/// \code
176
/// Tens<TensKind<Compl>,double> cicc;
177
/// conj(conj(cicc)); // returns cicc
178
/// \endcode
179
#
define
CANCEL_DUPLICATED_UNARY_SMET_CALL
(
CALLER
,
/*!< Name of builder */
180
UNARY_SMET
)
/*!< Type to un-nest */
181
/*! Simplify CALLER(UNARY_SMET) expression */
182
/*! */
183
/*! Returns the nested reference */
184
template
<
typename
T
,
/* Type of the expression */
185
typename
RrT
=
RemRef
<
T
>
,
/* T without ref attributes */
186
typename
Ref
=
typename
RrT
::
Ref
,
/* Type of the reference */
187
typename
RrRef
=
RemRef
<
Ref
>
,
/* Ref without ref attributes */
188
bool
SmETIsLvalue
=
isLvalue
<
RrT
>
,
/* Detect if SmET is an lvalue */
189
bool
RefIsLvalue
=
isLvalue
<
RrRef
>
,
/* Detect if Ref is an lvalue */
190
bool
RefIsStoring
=
isStoring
<
RrRef
>
,
/* Detect if Ref is storing */
191
bool
RetByRef
=
RefIsStoring
or
/* Returns by val if Ref is storing, or */
192
RefIsLvalue
or
SmETIsLvalue
,
/* lvalue is involved */
193
typename
Ret
=
Conditional
<
RetByRef
,
RrRef
&
,
RrRef
>
,
/* Returned type */
194
SFINAE_ON_TEMPLATE_ARG
(
is
##
UNARY_SMET
<
RrT
>
)
>
/* Enable only for the UNARY_SMET required */
195
Ret
CALLER
(
T
&&
smet
)
/*!< Quantity to un-nest */
196
{
197
if
constexpr
(
0
)
198
{
199
constexpr
bool
SmETIsConst
=
isConst
<
T
>
;
200
constexpr
bool
RefIsConst
=
isConst
<
Ref
>
;
201
202
using
namespace
std
;
203
cout
<<
"Removing duplicated call "
#
CALLER
<<
" "
<<
__PRETTY_FUNCTION__
<<
endl
;
204
constexpr
bool
SmETIs
=
std
::
is_reference
<
T
>
::
value
;
205
constexpr
bool
RefIs
=
std
::
is_reference
<
Ref
>
::
value
;
206
cout
<<
" SmETIsLvalue: "
<<
SmETIsLvalue
<<
endl
;
207
cout
<<
" SmETIs: "
<<
SmETIs
<<
endl
;
208
cout
<<
" SmETIsConst: "
<<
SmETIsConst
<<
endl
;
209
cout
<<
" RefIsLvalue: "
<<
RefIsLvalue
<<
endl
;
210
cout
<<
" RefIs: "
<<
RefIs
<<
endl
;
211
cout
<<
" RefIsConst: "
<<
RefIsConst
<<
endl
;
212
}
213
214
return
static_cast
<
Ret
>
(
smet
.
ref
)
;
215
}
216
SWALLOW_SEMICOLON_AT_GLOBAL_SCOPE
217
218
/// Implements a duplicated-call absorber
219
///
220
/// Example
221
/// \code
222
/// Tens<TensKind<Compl>,double> cicc;
223
/// wrap(wrap(cicc)); // returns wrap(cicc)
224
/// \endcode
225
#
define
ABSORB_DUPLICATED_UNARY_SMET_CALL
(
CALLER
,
/*!< Name of builder */
226
UNARY_SMET
)
/*!< Type to absorb */
227
/*! Simplify CALLER(UNARY_SMET) expression */
228
/*! */
229
/*! Returns the reference */
230
template
<
typename
D
,
/* Type of the nested UNARY_SMET */
231
SFINAE_ON_TEMPLATE_ARG
(
is
##
UNARY_SMET
<
D
>
)
>
/* Enable only for the UNARY_SMET required */
232
DECLAUTO
CALLER
(
D
&&
smet
)
/*!< UnarySmET to absorb */
233
{
234
return
forw
<
D
>
(
smet
)
;
235
}
236
SWALLOW_SEMICOLON_AT_GLOBAL_SCOPE
237
238
/// Defines a simple way to swap nested UnarySmET
239
///
240
/// \todo we need to implement the same check done for
241
/// CANCEL_DUPLICATED_UNARY_SMET_CALL
242
#
define
UNARY_SMET_GOES_INSIDE
(
EXT_FUN
,
/*!< External builder */
243
UNARY_SMET
,
/*!< Name of the SmET */
244
INT_FUN
)
/*!< Internal builder */
245
/*! Simplify EXT_FUN(UNARY_SMET u) expression */
246
/*! */
247
/*! Returns INT_FUN(EXT_FUN(u.ref)) */
248
template
<
typename
D
,
/* Type of the nested UNARY_SMET */
249
SFINAE_ON_TEMPLATE_ARG
(
is
##
UNARY_SMET
<
D
>
)
>
/* Enable only for the UNARY_SMET required */
250
DECLAUTO
EXT_FUN
(
D
&&
smet
)
/*!< UnarySmET to nest */
251
{
252
return
INT_FUN
(
EXT_FUN
(
smet
.
ref
)
)
;
253
}
254
SWALLOW_SEMICOLON_AT_GLOBAL_SCOPE
255
256
/// Defines a simple way to swap an UnarySmET from rhs to lhs
257
///
258
/// \todo why can't we make only const & on rhs?
259
/// \todo we need to enforce SmET
260
#
define
UNARY_SMET_GOES_ON_LHS
(
LHS_FUN
,
/*!< External builder */
261
UNARY_SMET
)
/*!< Name of the SmET */
262
/*! Simplify EXT_FUN(UNARY_SMET u) expression */
263
/*! */
264
/*! Returns INT_FUN(EXT_FUN(u.ref)) */
265
template
<
typename
Lhs
,
/* Type of the lhs SmET */
266
typename
Rhs
,
/* Type of the rhs UNARY_SMET */
267
SFINAE_ON_TEMPLATE_ARG
(
is
##
UNARY_SMET
<
Rhs
>
)
>
/* Enable only for the UNARY_SMET required */
268
void
assign
(
Lhs
&&
lhs
,
/*!< Lhs of the assignement */
269
Rhs
&&
rhs
)
/*!< Rhs of the assignement, to free from UNARY_SMET */
270
{
271
if
(
1
)
272
{
273
using
namespace
std
;
274
cout
<<
"Moving "
#
UNARY_SMET
"to lhs"
<<
endl
;
275
}
276
assign
(
LHS_FUN
(
forw
<
Lhs
>
(
lhs
)
)
,
rhs
.
ref
)
;
277
}
278
SWALLOW_SEMICOLON_AT_GLOBAL_SCOPE
279
280
}
281
#
endif
282
283
#
endif
include
smet
UnarySmET.hpp
Generated by
1.8.11