Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
amdis
amdis-core
Commits
975fc4c7
Commit
975fc4c7
authored
Dec 16, 2019
by
Praetorius, Simon
Browse files
replaced implementation of static Size template with generic constexpr function
parent
cfa2b1d9
Changes
29
Hide whitespace changes
Inline
Side-by-side
src/amdis/common/Apply.hpp
View file @
975fc4c7
...
...
@@ -32,7 +32,7 @@ namespace AMDiS
constexpr
decltype
(
auto
)
apply
(
F
&&
f
,
Tuple
&&
t
)
{
return
Impl_
::
apply_impl
(
FWD
(
f
),
FWD
(
t
),
std
::
make_index_sequence
<
Size_v
<
std
::
remove_referenc
e_
t
<
Tuple
>>
>
{});
std
::
make_index_sequence
<
static_siz
e_
v
<
Tuple
>>
{});
}
template
<
class
Functor
,
class
...
Args
>
...
...
src/amdis/common/ForEach.hpp
View file @
975fc4c7
...
...
@@ -41,7 +41,7 @@ namespace AMDiS
template
<
class
Tuple
,
class
Functor
>
constexpr
void
for_each
(
Tuple
&&
tuple
,
Functor
&&
f
)
{
Tools
::
for_each
(
std
::
make_index_sequence
<
Size_v
<
std
::
remove_referenc
e_
t
<
Tuple
>>
>
{},
FWD
(
tuple
),
FWD
(
f
));
Tools
::
for_each
(
std
::
make_index_sequence
<
static_siz
e_
v
<
Tuple
>>
{},
FWD
(
tuple
),
FWD
(
f
));
}
...
...
src/amdis/common/HybridSize.hpp
View file @
975fc4c7
...
...
@@ -2,13 +2,11 @@
#include <utility>
#include <dune/common/indices.hh>
#include <dune/common/rangeutilities.hh>
#include <dune/common/typeutilities.hh>
#include <amdis/common/Access.hpp>
#include <amdis/common/Concepts.hpp>
#include <amdis/common/Index.hpp>
#include <amdis/common/StaticSize.hpp>
namespace
AMDiS
...
...
@@ -33,10 +31,10 @@ namespace AMDiS
* of entries as integer value. Otherwise a `std::integral_constant` is returned.
**/
template
<
class
Vector
>
implementation
-
defined
hybrid
S
ize
(
Vector
const
&
vec
);
implementation
-
defined
hybrid
_s
ize
(
Vector
const
&
vec
);
/// Return either an IntegralRange or a StaticIntegralRange of the indices to
/// access the vector, depending on the type of \ref hybrid
S
ize(vec)
/// access the vector, depending on the type of \ref hybrid
_s
ize(vec)
template
<
class
Vector
>
implementation
-
defined
hybridElements
(
Vector
const
&
vec
);
...
...
@@ -46,10 +44,10 @@ namespace AMDiS
* of rows as integer value. Otherwise a `std::integral_constant` is returned.
**/
template
<
class
Matrix
>
implementation
-
defined
hybrid
NumR
ows
(
Matrix
const
&
mat
);
implementation
-
defined
hybrid
_num_r
ows
(
Matrix
const
&
mat
);
/// Return either an IntegralRange or a StaticIntegralRange of the indices to
/// access the rows of the matrix, depending on the type of \ref hybrid
NumR
ows(mat)
/// access the rows of the matrix, depending on the type of \ref hybrid
_num_r
ows(mat)
template
<
class
Matrix
>
implementation
-
defined
hybridRows
(
Matrix
const
&
mat
);
...
...
@@ -59,10 +57,10 @@ namespace AMDiS
* of columns as integer value. Otherwise a `std::integral_constant` is returned.
**/
template
<
class
Matrix
>
implementation
-
defined
hybrid
NumC
ols
(
Matrix
const
&
mat
);
implementation
-
defined
hybrid
_num_c
ols
(
Matrix
const
&
mat
);
/// Return either an IntegralRange or a StaticIntegralRange of the indices to
/// access the columns of the matrix, depending on the type of \ref hybrid
NumC
ols(mat)
/// access the columns of the matrix, depending on the type of \ref hybrid
_num_c
ols(mat)
template
<
class
Matrix
>
implementation
-
defined
hybridCols
(
Matrix
const
&
mat
);
#else
...
...
@@ -71,29 +69,32 @@ namespace AMDiS
{
template
<
class
Vector
,
REQUIRES
(
Concepts
::
DynamicVectorAccessible_t
<
Vector
>
::
value
)
>
auto
hybrid
S
ize
(
Vector
const
&
vec
,
Dune
::
PriorityTag
<
3
>
)
auto
hybrid
_s
ize
(
Vector
const
&
vec
,
Dune
::
PriorityTag
<
2
>
)
->
decltype
(
vec
.
size
())
{
return
vec
.
size
();
}
template
<
class
Vector
,
REQUIRES
(
not
Concepts
::
DynamicVectorAccessible_t
<
Vector
>
::
value
)
>
constexpr
index_t
<
Vector
::
dimension
>
hybridSize
(
Vector
const
&
vec
,
Dune
::
PriorityTag
<
2
>
)
{
return
{};
}
REQUIRES
(
Concepts
::
DynamicVectorAccessible_t
<
Vector
>
::
value
)
>
auto
hybrid_size
(
Vector
const
&
vec
,
Dune
::
PriorityTag
<
1
>
)
->
decltype
(
size
(
vec
))
{
return
size
(
vec
);
}
template
<
class
Vector
,
REQUIRES
(
not
Concepts
::
DynamicVectorAccessible_t
<
Vector
>
::
value
)
>
constexpr
Size_t
<
Vector
>
hybridSize
(
Vector
const
&
vec
,
Dune
::
PriorityTag
<
1
>
)
{
return
{};
}
template
<
class
Vector
>
auto
hybrid_size
(
Vector
const
&
vec
,
Dune
::
PriorityTag
<
0
>
)
{
return
AMDiS
::
static_size
(
vec
);
}
}
// end namespace Impl
template
<
class
Vector
>
auto
hybrid
S
ize
(
Vector
const
&
vec
)
auto
hybrid
_s
ize
(
Vector
const
&
vec
)
{
return
Impl
::
hybrid
S
ize
(
vec
,
Dune
::
PriorityTag
<
42
>
{});
return
Impl
::
hybrid
_s
ize
(
vec
,
Dune
::
PriorityTag
<
42
>
{});
}
template
<
class
Vector
>
auto
hybridElements
(
Vector
const
&
vec
)
{
return
Dune
::
range
(
hybrid
S
ize
(
vec
));
return
Dune
::
range
(
hybrid
_s
ize
(
vec
));
}
...
...
@@ -101,39 +102,42 @@ namespace AMDiS
{
template
<
class
Matrix
,
REQUIRES
(
Concepts
::
DynamicMatrixAccessible_t
<
Matrix
>
::
value
)
>
auto
hybrid
NumR
ows
(
Matrix
const
&
mat
,
Dune
::
PriorityTag
<
5
>
)
auto
hybrid
_num_r
ows
(
Matrix
const
&
mat
,
Dune
::
PriorityTag
<
5
>
)
->
decltype
(
mat
.
num_rows
())
{
return
mat
.
num_rows
();
}
template
<
class
Matrix
,
REQUIRES
(
Concepts
::
DynamicMatrixAccessible_t
<
Matrix
>
::
value
)
>
auto
hybrid
NumR
ows
(
Matrix
const
&
mat
,
Dune
::
PriorityTag
<
4
>
)
auto
hybrid
_num_r
ows
(
Matrix
const
&
mat
,
Dune
::
PriorityTag
<
4
>
)
->
decltype
(
mat
.
N
())
{
return
mat
.
N
();
}
template
<
class
Matrix
,
REQUIRES
(
Concepts
::
DynamicMatrixAccessible_t
<
Matrix
>
::
value
)
>
auto
hybrid
NumR
ows
(
Matrix
const
&
mat
,
Dune
::
PriorityTag
<
3
>
)
auto
hybrid
_num_r
ows
(
Matrix
const
&
mat
,
Dune
::
PriorityTag
<
3
>
)
->
decltype
(
mat
.
rows
())
{
return
mat
.
rows
();
}
template
<
class
Matrix
,
REQUIRES
(
not
Concepts
::
DynamicMatrixAccessible_t
<
Matrix
>
::
value
)
>
constexpr
index_t
<
Matrix
::
rows
>
hybridNumRows
(
Matrix
const
&
mat
,
Dune
::
PriorityTag
<
2
>
)
{
return
{};
}
REQUIRES
(
Concepts
::
DynamicMatrixAccessible_t
<
Matrix
>
::
value
)
>
auto
hybrid_num_rows
(
Matrix
const
&
mat
,
Dune
::
PriorityTag
<
2
>
)
->
decltype
(
num_rows
(
mat
))
{
return
num_rows
(
mat
);
}
template
<
class
Matrix
,
REQUIRES
(
not
Concepts
::
DynamicMatrixAccessible_t
<
Matrix
>
::
value
)
>
constexpr
Rows_t
<
Matrix
>
hybridNumRows
(
Matrix
const
&
mat
,
Dune
::
PriorityTag
<
1
>
)
{
return
{};
}
template
<
class
Matrix
>
auto
hybrid_num_rows
(
Matrix
const
&
mat
,
Dune
::
PriorityTag
<
0
>
)
{
return
AMDiS
::
static_num_rows
(
mat
);
}
}
// end namespace Impl
template
<
class
Matrix
>
auto
hybrid
NumR
ows
(
Matrix
const
&
mat
)
auto
hybrid
_num_r
ows
(
Matrix
const
&
mat
)
{
return
Impl
::
hybrid
NumR
ows
(
mat
,
Dune
::
PriorityTag
<
42
>
{});
return
Impl
::
hybrid
_num_r
ows
(
mat
,
Dune
::
PriorityTag
<
42
>
{});
}
template
<
class
Matrix
>
auto
hybridRows
(
Matrix
const
&
mat
)
{
return
Dune
::
range
(
hybrid
NumR
ows
(
mat
));
return
Dune
::
range
(
hybrid
_num_r
ows
(
mat
));
}
...
...
@@ -141,39 +145,42 @@ namespace AMDiS
{
template
<
class
Matrix
,
REQUIRES
(
Concepts
::
DynamicMatrixAccessible_t
<
Matrix
>
::
value
)
>
auto
hybrid
NumC
ols
(
Matrix
const
&
mat
,
Dune
::
PriorityTag
<
5
>
)
auto
hybrid
_num_c
ols
(
Matrix
const
&
mat
,
Dune
::
PriorityTag
<
5
>
)
->
decltype
(
mat
.
num_rows
())
{
return
mat
.
num_cols
();
}
template
<
class
Matrix
,
REQUIRES
(
Concepts
::
DynamicMatrixAccessible_t
<
Matrix
>
::
value
)
>
auto
hybrid
NumC
ols
(
Matrix
const
&
mat
,
Dune
::
PriorityTag
<
4
>
)
auto
hybrid
_num_c
ols
(
Matrix
const
&
mat
,
Dune
::
PriorityTag
<
4
>
)
->
decltype
(
mat
.
M
())
{
return
mat
.
M
();
}
template
<
class
Matrix
,
REQUIRES
(
Concepts
::
DynamicMatrixAccessible_t
<
Matrix
>
::
value
)
>
auto
hybrid
NumC
ols
(
Matrix
const
&
mat
,
Dune
::
PriorityTag
<
3
>
)
auto
hybrid
_num_c
ols
(
Matrix
const
&
mat
,
Dune
::
PriorityTag
<
3
>
)
->
decltype
(
mat
.
cols
())
{
return
mat
.
cols
();
}
template
<
class
Matrix
,
REQUIRES
(
not
Concepts
::
DynamicMatrixAccessible_t
<
Matrix
>
::
value
)
>
constexpr
index_t
<
Matrix
::
cols
>
hybridNumCols
(
Matrix
const
&
mat
,
Dune
::
PriorityTag
<
2
>
)
{
return
{};
}
REQUIRES
(
Concepts
::
DynamicMatrixAccessible_t
<
Matrix
>
::
value
)
>
auto
hybrid_num_cols
(
Matrix
const
&
mat
,
Dune
::
PriorityTag
<
2
>
)
->
decltype
(
num_cols
(
mat
))
{
return
num_cols
(
mat
);
}
template
<
class
Matrix
,
REQUIRES
(
not
Concepts
::
DynamicMatrixAccessible_t
<
Matrix
>
::
value
)
>
constexpr
Cols_t
<
Matrix
>
hybridNumCols
(
Matrix
const
&
mat
,
Dune
::
PriorityTag
<
1
>
)
{
return
{};
}
template
<
class
Matrix
>
auto
hybrid_num_cols
(
Matrix
const
&
mat
,
Dune
::
PriorityTag
<
0
>
)
{
return
AMDiS
::
static_num_cols
(
mat
);
}
}
// end namespace Impl
template
<
class
Matrix
>
auto
hybrid
NumC
ols
(
Matrix
const
&
mat
)
auto
hybrid
_num_c
ols
(
Matrix
const
&
mat
)
{
return
Impl
::
hybrid
NumC
ols
(
mat
,
Dune
::
PriorityTag
<
42
>
{});
return
Impl
::
hybrid
_num_c
ols
(
mat
,
Dune
::
PriorityTag
<
42
>
{});
}
template
<
class
Matrix
>
auto
hybridCols
(
Matrix
const
&
mat
)
{
return
Dune
::
range
(
hybrid
NumC
ols
(
mat
));
return
Dune
::
range
(
hybrid
_num_c
ols
(
mat
));
}
#endif // DOXYGEN
...
...
src/amdis/common/MultiTypeMatrix.hpp
View file @
975fc4c7
...
...
@@ -72,7 +72,7 @@ namespace AMDiS
/// Assignment of real number to all tuple elements
MultiTypeMatrix
&
operator
=
(
real_type
value
)
{
Tools
::
for_each
(
*
this
,
[
value
](
auto
&
fv
)
{
fv
=
value
;
});
Tools
::
for_each
(
as_tuple
()
,
[
value
](
auto
&
fv
)
{
fv
=
value
;
});
return
*
this
;
}
...
...
@@ -93,44 +93,44 @@ namespace AMDiS
// Scaling of all tuple elements by a constant value
MultiTypeMatrix
&
operator
*=
(
real_type
value
)
{
Tools
::
for_each
(
*
this
,
[
value
](
auto
&
fv
)
{
fv
*=
value
;
});
Tools
::
for_each
(
as_tuple
()
,
[
value
](
auto
&
fv
)
{
fv
*=
value
;
});
return
*
this
;
}
// Scaling of all tuple elements by the inverse of a constant value
MultiTypeMatrix
&
operator
/=
(
real_type
value
)
{
Tools
::
for_each
(
*
this
,
[
value
](
auto
&
fv
)
{
fv
/=
value
;
});
Tools
::
for_each
(
as_tuple
()
,
[
value
](
auto
&
fv
)
{
fv
/=
value
;
});
return
*
this
;
}
/// Const access to the tuple elements
template
<
std
::
size_t
I
,
std
::
size_t
J
>
decltype
(
auto
)
operator
()(
const
index_t
<
I
>
&
,
const
index_t
<
J
>
&
)
const
decltype
(
auto
)
operator
()(
index_t
<
I
>
const
i
,
index_t
<
J
>
const
j
)
const
{
return
std
::
get
<
J
>
(
std
::
get
<
I
>
(
*
this
)
)
;
return
(
*
this
)
[
i
][
j
]
;
}
/// Mutable access to the tuple elements
template
<
std
::
size_t
I
,
std
::
size_t
J
>
decltype
(
auto
)
operator
()(
const
index_t
<
I
>
&
,
const
index_t
<
J
>
&
)
decltype
(
auto
)
operator
()(
index_t
<
I
>
const
i
,
index_t
<
J
>
const
j
)
{
return
std
::
get
<
J
>
(
std
::
get
<
I
>
(
*
this
)
)
;
return
(
*
this
)
[
i
][
j
]
;
}
/// Const access to the rows
template
<
std
::
size_t
I
>
decltype
(
auto
)
operator
[](
const
index_t
<
I
>
&
)
const
decltype
(
auto
)
operator
[](
index_t
<
I
>
const
)
const
{
return
std
::
get
<
I
>
(
*
this
);
return
std
::
get
<
I
>
(
as_tuple
()
);
}
/// Mutable access to the rows
template
<
std
::
size_t
I
>
decltype
(
auto
)
operator
[](
const
index_t
<
I
>
&
)
decltype
(
auto
)
operator
[](
index_t
<
I
>
const
)
{
return
std
::
get
<
I
>
(
*
this
);
return
std
::
get
<
I
>
(
as_tuple
()
);
}
/// Return number of elements of the tuple
...
...
@@ -149,17 +149,10 @@ namespace AMDiS
{
return
rows
;
}
};
namespace
Impl
{
template
<
class
...
Rows
>
struct
RowsImpl
<
MultiTypeMatrix
<
Rows
...
>>
:
std
::
integral_constant
<
std
::
size_t
,
sizeof
...(
Rows
)
>
{};
template
<
class
Row0
,
class
...
Rows
>
struct
ColsImpl
<
MultiTypeMatrix
<
Row0
,
Rows
...
>>
:
SizeImpl
<
Row0
>
{};
}
private:
std
::
tuple
<
Rows
...
>&
as_tuple
()
{
return
*
this
;
}
std
::
tuple
<
Rows
...
>
const
&
as_tuple
()
const
{
return
*
this
;
}
};
}
// end namespace AMDiS
src/amdis/common/MultiTypeVector.hpp
View file @
975fc4c7
...
...
@@ -65,50 +65,50 @@ namespace AMDiS
/// Assignment of real number to all tuple elements
MultiTypeVector
&
operator
=
(
real_type
value
)
{
Tools
::
for_each
(
*
this
,
[
value
](
auto
&
fv
)
{
fv
=
value
;
});
Tools
::
for_each
(
as_tuple
()
,
[
value
](
auto
&
fv
)
{
fv
=
value
;
});
return
*
this
;
}
// Compound assignment operator +=
MultiTypeVector
&
operator
+=
(
MultiTypeVector
const
&
that
)
{
Tools
::
for_range
<
0
,
dimension
>
([
&
that
,
this
](
auto
const
_
i
)
{
(
*
this
)[
_
i
]
+=
that
[
_
i
];
});
Tools
::
for_range
<
0
,
dimension
>
([
&
that
,
this
](
auto
const
i
)
{
(
*
this
)[
i
]
+=
that
[
i
];
});
return
*
this
;
}
// Compound assignment operator -=
MultiTypeVector
&
operator
-=
(
MultiTypeVector
const
&
that
)
{
Tools
::
for_range
<
0
,
dimension
>
([
&
that
,
this
](
auto
const
_
i
)
{
(
*
this
)[
_
i
]
-=
that
[
_
i
];
});
Tools
::
for_range
<
0
,
dimension
>
([
&
that
,
this
](
auto
const
i
)
{
(
*
this
)[
i
]
-=
that
[
i
];
});
return
*
this
;
}
// Scaling of all tuple elements by a constant value
MultiTypeVector
&
operator
*=
(
real_type
value
)
{
Tools
::
for_each
(
*
this
,
[
value
](
auto
&
fv
)
{
fv
*=
value
;
});
Tools
::
for_each
(
as_tuple
()
,
[
value
](
auto
&
fv
)
{
fv
*=
value
;
});
return
*
this
;
}
// Scaling of all tuple elements by the inverse of a constant value
MultiTypeVector
&
operator
/=
(
real_type
value
)
{
Tools
::
for_each
(
*
this
,
[
value
](
auto
&
fv
)
{
fv
/=
value
;
});
Tools
::
for_each
(
as_tuple
()
,
[
value
](
auto
&
fv
)
{
fv
/=
value
;
});
return
*
this
;
}
/// Const access to the tuple elements
template
<
std
::
size_t
I
>
decltype
(
auto
)
operator
[](
const
index_t
<
I
>
&
)
const
decltype
(
auto
)
operator
[](
index_t
<
I
>
const
)
const
{
return
std
::
get
<
I
>
(
*
this
);
return
std
::
get
<
I
>
(
as_tuple
()
);
}
/// Mutable access to the tuple elements
template
<
std
::
size_t
I
>
decltype
(
auto
)
operator
[](
const
index_t
<
I
>
&
)
decltype
(
auto
)
operator
[](
index_t
<
I
>
const
)
{
return
std
::
get
<
I
>
(
*
this
);
return
std
::
get
<
I
>
(
as_tuple
()
);
}
/// Const access to the vector using multi-indices
...
...
@@ -132,13 +132,10 @@ namespace AMDiS
{
return
dimension
;
}
};
namespace
Impl
{
template
<
class
...
Ts
>
struct
SizeImpl
<
MultiTypeVector
<
Ts
...
>>
:
std
::
integral_constant
<
std
::
size_t
,
sizeof
...(
Ts
)
>
{};
}
private:
std
::
tuple
<
FV
...
>&
as_tuple
()
{
return
*
this
;
}
std
::
tuple
<
FV
...
>
const
&
as_tuple
()
const
{
return
*
this
;
}
};
}
// end namespace AMDiS
src/amdis/common/QuadMath.hpp
View file @
975fc4c7
...
...
@@ -86,15 +86,24 @@ namespace AMDiS
{
template
<
>
struct
SizeImpl
<
Dune
::
Float128
>
:
std
::
integral_constant
<
std
::
size_t
,
1
>
{};
{
static
constexpr
auto
eval
(
Dune
::
Float128
)
->
std
::
integral_constant
<
std
::
size_t
,
1
>
{
return
{};
}
};
template
<
>
struct
RowsImpl
<
Dune
::
Float128
>
:
std
::
integral_constant
<
std
::
size_t
,
1
>
{};
struct
NumRowsImpl
<
Dune
::
Float128
>
{
static
constexpr
auto
eval
(
Dune
::
Float128
)
->
std
::
integral_constant
<
std
::
size_t
,
1
>
{
return
{};
}
};
template
<
>
struct
ColsImpl
<
Dune
::
Float128
>
:
std
::
integral_constant
<
std
::
size_t
,
1
>
{};
struct
NumColsImpl
<
Dune
::
Float128
>
{
static
constexpr
auto
eval
(
Dune
::
Float128
)
->
std
::
integral_constant
<
std
::
size_t
,
1
>
{
return
{};
}
};
}
// end namespace Impl
...
...
src/amdis/common/Range.hpp
View file @
975fc4c7
...
...
@@ -39,11 +39,6 @@ namespace AMDiS
template
<
std
::
size_t
I
,
class
Int
,
Int
begin
,
Int
end
>
constexpr
auto
get
(
range_impl
<
Int
,
begin
,
end
>
const
&
r
)
{
return
r
[
index_
<
I
>
];
}
/// Return the size of the range
template
<
class
Int
,
Int
I
,
Int
J
>
struct
SizeImpl
<
range_impl
<
Int
,
I
,
J
>>
:
std
::
integral_constant
<
std
::
size_t
,
std
::
size_t
(
J
-
I
)
>
{};
}
// end namespace Impl
template
<
std
::
size_t
I
,
std
::
size_t
J
>
...
...
src/amdis/common/StaticSize.hpp
View file @
975fc4c7
...
...
@@ -4,152 +4,276 @@
#include <tuple>
#include <type_traits>
#include <dune/common/typeutilities.hh>
#include <amdis/common/TypeTraits.hpp>
namespace
Dune
{
// forward declarations
template
<
class
T
,
int
N
,
int
M
>
class
FieldMatrix
;
template
<
class
T
,
int
N
>
class
FieldVector
;
template
<
class
...
Ts
>
class
TupleVector
;
template
<
class
Row0
,
class
...
Rows
>
class
MultiTypeBlockMatrix
;
template
<
class
...
Ts
>
class
MultiTypeBlockVector
;
}
namespace
Eigen
{
template
<
typename
_Scalar
,
int
_Rows
,
int
_Cols
,
int
_Options
,
int
_MaxRows
,
int
_MaxCols
>
class
Matrix
;
}
#if HAVE_MTL
#include <boost/numeric/mtl/operation/static_size.hpp>
#endif
namespace
AMDiS
{
namespace
Impl
{
template
<
class
Tuple
,
class
=
void
>
struct
SizeImpl
:
std
::
integral_constant
<
std
::
size_t
,
0
>
{};
template
<
class
...
Args
>
struct
SizeImpl
<
std
::
tuple
<
Args
...
>>
:
std
::
integral_constant
<
std
::
size_t
,
sizeof
...(
Args
)
>
{};
template
<
class
Arg0
,
class
Arg1
>
struct
SizeImpl
<
std
::
pair
<
Arg0
,
Arg1
>>
:
std
::
integral_constant
<
std
::
size_t
,
2
>
{};
template
<
class
T
,
std
::
size_t
N
>
struct
SizeImpl
<
std
::
array
<
T
,
N
>>
:
std
::
integral_constant
<
std
::
size_t
,
N
>
{};
template
<
class
T
,
int
N
>
struct
SizeImpl
<
Dune
::
FieldVector
<
T
,
N
>>
:
std
::
integral_constant
<
std
::
size_t
,
N
>
{};
template
<
class
T
,
int
N
,
int
M
>
struct
SizeImpl
<
Dune
::
FieldMatrix
<
T
,
N
,
M
>>
:
std
::
integral_constant
<
std
::
size_t
,
N
*
M
>
{};
template
<
class
...
Ts
>
struct
SizeImpl
<
Dune
::
TupleVector
<
Ts
...
>>
:
std
::
integral_constant
<
std
::
size_t
,
sizeof
...(
Ts
)
>
{};
template
<
class
...
Ts
>
struct
SizeImpl
<
Dune
::
MultiTypeBlockVector
<
Ts
...
>>
:
std
::
integral_constant
<
std
::
size_t
,
sizeof
...(
Ts
)
>
{};
template
<
class
T
,
int
N
,
int
...
opts
>
struct
SizeImpl
<
Eigen
::
Matrix
<
T
,
N
,
1
,
opts
...
>>
:
std
::
integral_constant
<
std
::
size_t
,
(
N
>=
0
?
std
::
size_t
(
N
)
:
0u
)
>
{};
template
<
class
T
,
int
N
,
int
...
opts
>
struct
SizeImpl
<
Eigen
::
Matrix
<
T
,
1
,
N
,
opts
...
>>
:
std
::
integral_constant
<
std
::
size_t
,
(
N
>=
0
?
std
::
size_t
(
N
)
:
0u
)
>
{};
// Specialization for arithmetic types
template
<
class
T
>
struct
SizeImpl
<
T
,
std
::
enable_if_t
<
std
::
is_arithmetic
<
T
>::
value
>
>
:
std
::
integral_constant
<
std
::
size_t
,
1
>
{};
template
<
class
Container
>
struct
SizeImpl
{
#if HAVE_MTL
// MTL4: Try if a mtl::static_size is specialized for class
template
<
class
T
>
static
constexpr
auto
eval
(
T
const
&
,
Dune
::
PriorityTag
<
6
>
)
->
decltype
(
std
::
integral_constant
<
std
::
size_t
,(
mtl
::
static_num_rows
<
T
>::
value
*
mtl
::
static_num_cols
<
T
>::
value
)
>
{})
{
return
{};
}
#endif
// Eigen: Try if a static SizeAtCompileTime constant is specified for class
template
<
class
T
>
static
constexpr
auto
eval
(
T
const
&
,
Dune
::
PriorityTag
<
5
>
)
->
decltype
(
std
::
integral_constant
<
std
::
size_t
,
T
::
SizeAtCompileTime
>
{})
{
return
{};
}
// Try if tuple_size is implemented for class
template
<
class
T
>
static
constexpr
auto
eval
(
T
const
&
,
Dune
::
PriorityTag
<
4
>
)
->
decltype
(
std
::
integral_constant
<
std
::
size_t
,
std
::
tuple_size
<
T
>::
value
>
{})
{
return
{};
}
// Try if a static dimension constant is specified for class
template
<
class
T
>
static
constexpr
auto
eval
(
T
const
&
,
Dune
::
PriorityTag
<
3
>
)
->
decltype
(
std
::
integral_constant
<
std
::
size_t
,
T
::
dimension
>
{})
{
return
{};
}
// Try if a static rows and cols constants are specified for class
template
<
class
T
>
static
constexpr
auto
eval
(
T
const
&
,
Dune
::
PriorityTag
<
2
>
)
->
decltype
(
std
::
integral_constant
<
std
::
size_t
,(
T
::
rows
*
T
::
cols
)
>
{})
{
return
{};
}
// Try if there's a static constexpr size()
template
<
class
T
>
static
constexpr
auto
eval
(
T
const
&
,
Dune
::
PriorityTag
<
1
>
)
->
decltype
(
std
::
integral_constant
<
std
::
size_t
,
T
::
size
()
>
{})
{
return
{};
}
// Arithmetic types have size 1 otherwise size is 0
template
<
class
T
>
static
constexpr
auto
eval
(
T
const
&
,
Dune
::
PriorityTag
<
0
>
)
->
decltype
(
std
::
integral_constant
<
std
::
size_t
,
(
std
::
is_arithmetic
<
T
>::
value
?
1
:
0
)
>
{})
{
return
{};
}
static
constexpr
auto
eval
(
Container
const
&
container
)
{
return
eval
(
container
,
Dune
::
PriorityTag
<
42
>
{});
}
};
}
// end namespace Impl
/// Get the number of elements in a tuple / pair / array / ...
template
<
class
T
>
constexpr
std
::
size_t
Size_v
=
Impl
::
SizeImpl
<
remove_cvref_t
<
T
>>::
value
;
template
<
class
T
>
using
Size_t
=
Impl
::
SizeImpl
<
remove_cvref_t
<
T
>>
;
namespace
Impl
/**
* \brief Return a static constant size of the container
*