SUNphi
1.0
Main Page
Related Pages
Namespaces
Classes
Files
File List
File Members
Indexer.hpp
Go to the documentation of this file.
1
#
ifndef
_INDEXER_HPP
2
#
define
_INDEXER_HPP
3
4
/// \file Indexer.hpp
5
///
6
/// \brief Header file for the definition of an indexer
7
8
#
ifdef
HAVE_CONFIG_H
9
#
include
<
config
.
hpp
>
10
#
endif
11
12
#
include
<
metaprogramming
/
TypeTraits
.
hpp
>
13
#
include
<
system
/
Memory
.
hpp
>
14
#
include
<
tens
/
TensKind
.
hpp
>
15
16
namespace
SUNphi
17
{
18
/// Indexer class to compute an index for a TensKind
19
///
20
/// Forward declaration
21
template
<
int
IDyn,
// Index of the current dynamic component
22
class
T,
// Generic type
23
class
=
FalseType
>
// Forbids instantiation
24
struct
_Indexer
:
ConstrainIsTensKind
<
T
>
25
{
26
};
27
28
/// Indexer class to compute an index for a TensKind
29
///
30
/// Recursive implementation definining a nested indexer and
31
/// calling it until no component is found. The check on types is
32
/// done in the externally visible routine.
33
template
<
int
IDyn
,
// Index of the current dynamic component in the list
34
class
H
,
// Current TensKind
35
class
...
Oth
>
// Other TensKind
36
struct
_Indexer
<
IDyn
,
TensKind
<
H
,
Oth
...>>
37
{
38
/// Size of the top-level class
39
static
constexpr
int
headSize
=
40
H
::
size
;
41
42
/// Check if this component is dynamic
43
static
constexpr
bool
thisDynamic
=
44
(
headSize
==
DYNAMIC
);
45
46
/// Nested TensKind
47
using
NestedTk
=
48
TensKind
<
Oth
...>;
49
50
/// Nested Dynamic index
51
static
constexpr
int
nestedIDyn
=
52
(
thisDynamic
?
IDyn
+1 :
IDyn
);
53
54
/// Nested indexer
55
using
Nested
=
56
_Indexer
<
nestedIDyn
,
NestedTk
>;
57
58
/// Compute the index, given a set of components
59
///
60
/// Internal implementation
61
/// \todo fix the int types
62
template
<
size_t
NTotDyn
,
// Total number of dynamic components
63
class
Head
,
// Current component type
64
class
...
Tail
,
// Other component types
65
class
=
ConstrainAreIntegrals
<
Head
,
Tail
...>>
// Constrain all types to be integral
66
static
constexpr
int
index
(
const
DynSizes
<
NTotDyn
>&
dynSizes
,
///< Dynamic sizes
67
const
int
in
,
///< External partial index
68
const
Head
&
head
,
///< Current component
69
const
Tail
&...
tail
)
///< Other components
70
{
71
// Constrain the components to be in the same number of the type
72
static_assert
(
sizeof
...(
Oth
)==
sizeof
...(
Tail
),
"Number of TensComp does not match number of passed components"
);
73
74
// Current component
75
const
int
thisComp
=
76
head
;
77
78
// Current size
79
const
int
size
=
80
thisDynamic
?
81
dynSizes
[
IDyn
]:
82
headSize
;
83
84
// Compute the result
85
int
out
=
thisComp
+
size
*
in
;
86
87
// Nested value
88
if
constexpr
(
sizeof
...(
Tail
)>0)
89
{
90
#
ifdef
DEBUG_INDEXER
91
printf
(
"Is Nested , thiscomp: %d , is Dyn: %d"
,
thisComp
,
thisDynamic
);
92
printf
(
", HeadSize: %d"
,
headSize
);
93
printf
(
", Size: %d"
,
size
);
94
printf
(
", %d"
,
IDyn
);
95
if
(
thisDynamic
)
printf
(
" %d"
,
dynSizes
[
IDyn
]);
96
printf
(
"\n"
);
97
#
endif
98
99
return
Nested
::
index
(
forw
<
const
DynSizes
<
NTotDyn
>>(
dynSizes
),
out
,
forw
<
const
Tail
>(
tail
)...);
100
}
101
else
102
{
103
#
ifdef
DEBUG_INDEXER
104
std
::
cout
<<
"Non-Nested , value: "
<<
out
<<
std
::
endl
;
105
#
endif
106
return
out
;
107
}
108
}
109
};
110
111
/// Index function for a TensKind
112
///
113
/// Wraps the call to the Indexer class method
114
/// The index is built in this way.
115
/// Let us assume three component case
116
///
117
/// \code
118
/// a+Na*(b+Nb*c)
119
/// \endcode
120
///
121
/// this is changed into a more homogeneous
122
///
123
/// \code
124
/// a+Na*(b+Nb*(c+Nc*0))
125
/// \endcode
126
///
127
/// so that every component needs to perform the following operation
128
///
129
/// \code
130
/// i+N*ext
131
/// \endcode
132
///
133
/// where \c ext is the result of the calculation for the outer
134
/// component. Starting from 0, the calculation ends when no more
135
/// component is present (terminating case).
136
template
<
class
TK
,
// Tensor Kind
137
size_t
NDynamic
,
// Number of dynamic components
138
class
...
Args
>
// Types of the components
139
static
constexpr
int
index
(
const
DynSizes
<
NDynamic
>&
dynSizes
,
///< Sizes of the dynamical components
140
const
Args
&...
args
)
///< Components index
141
{
142
static_assert
(
TK
::
nDynamic
==
NDynamic
,
"Nuber of dynamic components sizes must agree with the TensKind one"
);
143
STATIC_ASSERT_ARE_INTEGRALS
(
Args
...);
144
145
#
ifdef
DEBUG_INDEXER
146
print
(
std
::
cout
,
"Components:"
,
args
...,
"\n"
);
147
#
endif
148
149
return
_Indexer
<0,
TK
>::
index
(
dynSizes
,0,
args
...);
150
}
151
}
152
153
#
endif
SUNphi::_Indexer
Definition:
Indexer.hpp:24
STATIC_ASSERT_ARE_INTEGRALS
#define STATIC_ASSERT_ARE_INTEGRALS(...)
Static assert if the types T are not an integer-like.
Definition:
TypeTraits.hpp:484
SUNphi::operator+
decltype(auto) operator+(T1 &&smet1, T2 &&smet2)
Implement smet1+smet2.
Definition:
Add.hpp:87
include
tens
Indexer.hpp
Generated by
1.8.11