Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
D
dune-common
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Core Modules
dune-common
Commits
75c4c424
Commit
75c4c424
authored
14 years ago
by
Jorrit Fahlke
Browse files
Options
Downloads
Patches
Plain Diff
[genericTransformTuple()] Transform tuple values à la ForEachType.
[[Imported from SVN: r6075]]
parent
9f986a42
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
dune/common/utility.hh
+357
-0
357 additions, 0 deletions
dune/common/utility.hh
with
357 additions
and
0 deletions
dune/common/utility.hh
+
357
−
0
View file @
75c4c424
...
...
@@ -196,6 +196,8 @@ namespace Dune {
\endcode
* Here, MyEvaluator is a helper struct that extracts the correct type from
* the storage types of the tuple defined by the tuple ATuple.
*
* \sa genericTransformTuple().
*/
template
<
template
<
class
>
class
TypeEvaluator
,
class
TupleType
>
class
ForEachType
{
...
...
@@ -295,6 +297,361 @@ namespace Dune {
};
#endif // !defined(DOXYGEN)
//////////////////////////////////////////////////////////////////////
//
// genericTranformTuple stuff
//
// genericTranformTuple() needs to be overloaded for each tuple size (we
// limit ourselves to tuple_size <= 10 here). For a given tuple size it
// needs to be overloaded for all combinations of const and non-const
// argument references. (On the one hand, we want to allow modifyable
// arguments, so const references alone are not sufficient. On the other
// hand, we also want to allow rvalues (literals) as argument, which do not
// bind to non-const references.)
//
// We can half the number of specializations required by introducing a
// function genericTransformTupleBackend(), which is overloaded for each
// tuple size and for const and non-const tuple arguments; the functor
// argument is always given as as (non-const) reference. When
// genericTranformTupleBackend() is called, the type of the Functor template
// parameter is the deduced as either "SomeType" or "const SomeType",
// depending on whether the function argument is a non-const or a const
// lvalue of type "SomeType". As explained above, this does not work for
// rvalues (i.e. literals).
//
// To make it work for literals of functors as well, we wrap the call to
// genericTransformTupleBackend() in a function genericTransformTuple().
// genericTransformTuple() needs to be overloaded for non-const and const
// tuples and functors -- 4 overloads only. Inside genericTransformTuple()
// the functor is an lvalue no matter whether the argument was an lvalue or
// an rvalue. There is no need need to overload genericTransformTuple() for
// all tuple sizes -- this is done by the underlying
// genericTransformTupleBackend().
// genericTransformTupleBackend() is an implementation detail -- hide it
// from Doxygen
#ifndef DOXYGEN
// 0-element tuple
// This is a special case: we touch neither the tuple nor the functor, so
// const references are sufficient and we don't need to overload
template
<
class
Functor
>
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
>
>::
Type
genericTransformTupleBackend
(
const
tuple
<>&
t
,
const
Functor
&
f
)
{
return
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
>
>::
Type
();
}
// 1-element tuple
template
<
class
T0
,
class
Functor
>
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
>
>::
Type
genericTransformTupleBackend
(
tuple
<
T0
>&
t
,
Functor
&
f
)
{
return
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
>
>::
Type
(
f
(
get
<
0
>
(
t
)));
}
template
<
class
T0
,
class
Functor
>
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
>
>::
Type
genericTransformTupleBackend
(
const
tuple
<
T0
>&
t
,
Functor
&
f
)
{
return
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
>
>::
Type
(
f
(
get
<
0
>
(
t
)));
}
// 2-element tuple
template
<
class
T0
,
class
T1
,
class
Functor
>
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
>
>::
Type
genericTransformTupleBackend
(
tuple
<
T0
,
T1
>&
t
,
Functor
&
f
)
{
return
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
>
>::
Type
(
f
(
get
<
0
>
(
t
)),
f
(
get
<
1
>
(
t
)));
}
template
<
class
T0
,
class
T1
,
class
Functor
>
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
>
>::
Type
genericTransformTupleBackend
(
const
tuple
<
T0
,
T1
>&
t
,
Functor
&
f
)
{
return
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
>
>::
Type
(
f
(
get
<
0
>
(
t
)),
f
(
get
<
1
>
(
t
)));
}
// 3-element tuple
template
<
class
T0
,
class
T1
,
class
T2
,
class
Functor
>
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
,
T2
>
>::
Type
genericTransformTupleBackend
(
tuple
<
T0
,
T1
,
T2
>&
t
,
Functor
&
f
)
{
return
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
,
T2
>
>::
Type
(
f
(
get
<
0
>
(
t
)),
f
(
get
<
1
>
(
t
)),
f
(
get
<
2
>
(
t
)));
}
template
<
class
T0
,
class
T1
,
class
T2
,
class
Functor
>
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
,
T2
>
>::
Type
genericTransformTupleBackend
(
const
tuple
<
T0
,
T1
,
T2
>&
t
,
Functor
&
f
)
{
return
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
,
T2
>
>::
Type
(
f
(
get
<
0
>
(
t
)),
f
(
get
<
1
>
(
t
)),
f
(
get
<
2
>
(
t
)));
}
// 4-element tuple
template
<
class
T0
,
class
T1
,
class
T2
,
class
T3
,
class
Functor
>
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
,
T2
,
T3
>
>::
Type
genericTransformTupleBackend
(
tuple
<
T0
,
T1
,
T2
,
T3
>&
t
,
Functor
&
f
)
{
return
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
,
T2
,
T3
>
>::
Type
(
f
(
get
<
0
>
(
t
)),
f
(
get
<
1
>
(
t
)),
f
(
get
<
2
>
(
t
)),
f
(
get
<
3
>
(
t
)));
}
template
<
class
T0
,
class
T1
,
class
T2
,
class
T3
,
class
Functor
>
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
,
T2
,
T3
>
>::
Type
genericTransformTupleBackend
(
const
tuple
<
T0
,
T1
,
T2
,
T3
>&
t
,
Functor
&
f
)
{
return
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
,
T2
,
T3
>
>::
Type
(
f
(
get
<
0
>
(
t
)),
f
(
get
<
1
>
(
t
)),
f
(
get
<
2
>
(
t
)),
f
(
get
<
3
>
(
t
)));
}
// 5-element tuple
template
<
class
T0
,
class
T1
,
class
T2
,
class
T3
,
class
T4
,
class
Functor
>
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
>
>::
Type
genericTransformTupleBackend
(
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
>&
t
,
Functor
&
f
)
{
return
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
>
>::
Type
(
f
(
get
<
0
>
(
t
)),
f
(
get
<
1
>
(
t
)),
f
(
get
<
2
>
(
t
)),
f
(
get
<
3
>
(
t
)),
f
(
get
<
4
>
(
t
)));
}
template
<
class
T0
,
class
T1
,
class
T2
,
class
T3
,
class
T4
,
class
Functor
>
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
>
>::
Type
genericTransformTupleBackend
(
const
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
>&
t
,
Functor
&
f
)
{
return
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
>
>::
Type
(
f
(
get
<
0
>
(
t
)),
f
(
get
<
1
>
(
t
)),
f
(
get
<
2
>
(
t
)),
f
(
get
<
3
>
(
t
)),
f
(
get
<
4
>
(
t
)));
}
// 6-element tuple
template
<
class
T0
,
class
T1
,
class
T2
,
class
T3
,
class
T4
,
class
T5
,
class
Functor
>
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
,
T5
>
>::
Type
genericTransformTupleBackend
(
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
,
T5
>&
t
,
Functor
&
f
)
{
return
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
,
T5
>
>::
Type
(
f
(
get
<
0
>
(
t
)),
f
(
get
<
1
>
(
t
)),
f
(
get
<
2
>
(
t
)),
f
(
get
<
3
>
(
t
)),
f
(
get
<
4
>
(
t
)),
f
(
get
<
5
>
(
t
)));
}
template
<
class
T0
,
class
T1
,
class
T2
,
class
T3
,
class
T4
,
class
T5
,
class
Functor
>
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
,
T5
>
>::
Type
genericTransformTupleBackend
(
const
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
,
T5
>&
t
,
Functor
&
f
)
{
return
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
,
T5
>
>::
Type
(
f
(
get
<
0
>
(
t
)),
f
(
get
<
1
>
(
t
)),
f
(
get
<
2
>
(
t
)),
f
(
get
<
3
>
(
t
)),
f
(
get
<
4
>
(
t
)),
f
(
get
<
5
>
(
t
)));
}
// 7-element tuple
template
<
class
T0
,
class
T1
,
class
T2
,
class
T3
,
class
T4
,
class
T5
,
class
T6
,
class
Functor
>
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
,
T5
,
T6
>
>::
Type
genericTransformTupleBackend
(
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
,
T5
,
T6
>&
t
,
Functor
&
f
)
{
return
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
,
T5
,
T6
>
>::
Type
(
f
(
get
<
0
>
(
t
)),
f
(
get
<
1
>
(
t
)),
f
(
get
<
2
>
(
t
)),
f
(
get
<
3
>
(
t
)),
f
(
get
<
4
>
(
t
)),
f
(
get
<
5
>
(
t
)),
f
(
get
<
6
>
(
t
)));
}
template
<
class
T0
,
class
T1
,
class
T2
,
class
T3
,
class
T4
,
class
T5
,
class
T6
,
class
Functor
>
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
,
T5
,
T6
>
>::
Type
genericTransformTupleBackend
(
const
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
,
T5
,
T6
>&
t
,
Functor
&
f
)
{
return
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
,
T5
,
T6
>
>::
Type
(
f
(
get
<
0
>
(
t
)),
f
(
get
<
1
>
(
t
)),
f
(
get
<
2
>
(
t
)),
f
(
get
<
3
>
(
t
)),
f
(
get
<
4
>
(
t
)),
f
(
get
<
5
>
(
t
)),
f
(
get
<
6
>
(
t
)));
}
// 8-element tuple
template
<
class
T0
,
class
T1
,
class
T2
,
class
T3
,
class
T4
,
class
T5
,
class
T6
,
class
T7
,
class
Functor
>
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
,
T5
,
T6
,
T7
>
>::
Type
genericTransformTupleBackend
(
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
,
T5
,
T6
,
T7
>&
t
,
Functor
&
f
)
{
return
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
,
T5
,
T6
,
T7
>
>::
Type
(
f
(
get
<
0
>
(
t
)),
f
(
get
<
1
>
(
t
)),
f
(
get
<
2
>
(
t
)),
f
(
get
<
3
>
(
t
)),
f
(
get
<
4
>
(
t
)),
f
(
get
<
5
>
(
t
)),
f
(
get
<
6
>
(
t
)),
f
(
get
<
7
>
(
t
)));
}
template
<
class
T0
,
class
T1
,
class
T2
,
class
T3
,
class
T4
,
class
T5
,
class
T6
,
class
T7
,
class
Functor
>
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
,
T5
,
T6
,
T7
>
>::
Type
genericTransformTupleBackend
(
const
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
,
T5
,
T6
,
T7
>&
t
,
Functor
&
f
)
{
return
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
,
T5
,
T6
,
T7
>
>::
Type
(
f
(
get
<
0
>
(
t
)),
f
(
get
<
1
>
(
t
)),
f
(
get
<
2
>
(
t
)),
f
(
get
<
3
>
(
t
)),
f
(
get
<
4
>
(
t
)),
f
(
get
<
5
>
(
t
)),
f
(
get
<
6
>
(
t
)),
f
(
get
<
7
>
(
t
)));
}
// 9-element tuple
template
<
class
T0
,
class
T1
,
class
T2
,
class
T3
,
class
T4
,
class
T5
,
class
T6
,
class
T7
,
class
T8
,
class
Functor
>
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
,
T5
,
T6
,
T7
,
T8
>
>::
Type
genericTransformTupleBackend
(
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
,
T5
,
T6
,
T7
,
T8
>&
t
,
Functor
&
f
)
{
return
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
,
T5
,
T6
,
T7
,
T8
>
>::
Type
(
f
(
get
<
0
>
(
t
)),
f
(
get
<
1
>
(
t
)),
f
(
get
<
2
>
(
t
)),
f
(
get
<
3
>
(
t
)),
f
(
get
<
4
>
(
t
)),
f
(
get
<
5
>
(
t
)),
f
(
get
<
6
>
(
t
)),
f
(
get
<
7
>
(
t
)),
f
(
get
<
8
>
(
t
)));
}
template
<
class
T0
,
class
T1
,
class
T2
,
class
T3
,
class
T4
,
class
T5
,
class
T6
,
class
T7
,
class
T8
,
class
Functor
>
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
,
T5
,
T6
,
T7
,
T8
>
>::
Type
genericTransformTupleBackend
(
const
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
,
T5
,
T6
,
T7
,
T8
>&
t
,
Functor
&
f
)
{
return
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
,
T5
,
T6
,
T7
,
T8
>
>::
Type
(
f
(
get
<
0
>
(
t
)),
f
(
get
<
1
>
(
t
)),
f
(
get
<
2
>
(
t
)),
f
(
get
<
3
>
(
t
)),
f
(
get
<
4
>
(
t
)),
f
(
get
<
5
>
(
t
)),
f
(
get
<
6
>
(
t
)),
f
(
get
<
7
>
(
t
)),
f
(
get
<
8
>
(
t
)));
}
// 10-element tuple
template
<
class
T0
,
class
T1
,
class
T2
,
class
T3
,
class
T4
,
class
T5
,
class
T6
,
class
T7
,
class
T8
,
class
T9
,
class
Functor
>
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
,
T5
,
T6
,
T7
,
T8
,
T9
>
>::
Type
genericTransformTupleBackend
(
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
,
T5
,
T6
,
T7
,
T8
,
T9
>&
t
,
Functor
&
f
)
{
return
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
,
T5
,
T6
,
T7
,
T8
,
T9
>
>::
Type
(
f
(
get
<
0
>
(
t
)),
f
(
get
<
1
>
(
t
)),
f
(
get
<
2
>
(
t
)),
f
(
get
<
3
>
(
t
)),
f
(
get
<
4
>
(
t
)),
f
(
get
<
5
>
(
t
)),
f
(
get
<
6
>
(
t
)),
f
(
get
<
7
>
(
t
)),
f
(
get
<
8
>
(
t
)),
f
(
get
<
9
>
(
t
)));
}
template
<
class
T0
,
class
T1
,
class
T2
,
class
T3
,
class
T4
,
class
T5
,
class
T6
,
class
T7
,
class
T8
,
class
T9
,
class
Functor
>
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
,
T5
,
T6
,
T7
,
T8
,
T9
>
>::
Type
genericTransformTupleBackend
(
const
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
,
T5
,
T6
,
T7
,
T8
,
T9
>&
t
,
Functor
&
f
)
{
return
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
tuple
<
T0
,
T1
,
T2
,
T3
,
T4
,
T5
,
T6
,
T7
,
T8
,
T9
>
>::
Type
(
f
(
get
<
0
>
(
t
)),
f
(
get
<
1
>
(
t
)),
f
(
get
<
2
>
(
t
)),
f
(
get
<
3
>
(
t
)),
f
(
get
<
4
>
(
t
)),
f
(
get
<
5
>
(
t
)),
f
(
get
<
6
>
(
t
)),
f
(
get
<
7
>
(
t
)),
f
(
get
<
8
>
(
t
)),
f
(
get
<
9
>
(
t
)));
}
#endif // ! defined(DOXYGEN)
//! transform a tuple object into another tuple object
/**
* \code
*#include <dune/common/utility.hh>
* \endcode
* This function does for the value of a tuple what ForEachType does for the
* type of a tuple: it transforms the value using a user-provided policy
* functor.
*
* \param t The tuple value to transform.
* \param f The functor to use to transform the values.
*
* The functor should have the following form:
* \code
struct Functor {
template<class> struct TypeEvaluator {
typedef user-defined Type;
};
template<class T>
typename TypeEvaluator<T>::Type operator()(T& val);
template<class T>
typename TypeEvaluator<T>::Type operator()(T& val) const;
template<class T>
typename TypeEvaluator<T>::Type operator()(const T& val);
template<class T>
typename TypeEvaluator<T>::Type operator()(const T& val) const;
};
* \endcode
* The member class template \c TypeEvaluator should be a class template
* suitable as the \c TypeEvaluator template parameter for ForEachType. The
* function call operator \c operator() is used to transform the value; only
* the signatures of \c operator() which are actually used must be present.
*
* There are overloaded definitions of genericTransformTuple() wich take
* constant tuple and functor arguments so rvalues are permissible as
* arguments here. These overloaded definitions are not documented
* seperately.
*/
template
<
class
Tuple
,
class
Functor
>
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
Tuple
>
::
Type
genericTransformTuple
(
Tuple
&
t
,
Functor
&
f
)
{
return
genericTransformTupleBackend
(
t
,
f
);
}
#ifndef DOXYGEN
template
<
class
Tuple
,
class
Functor
>
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
Tuple
>
::
Type
genericTransformTuple
(
const
Tuple
&
t
,
Functor
&
f
)
{
return
genericTransformTupleBackend
(
t
,
f
);
}
template
<
class
Tuple
,
class
Functor
>
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
Tuple
>
::
Type
genericTransformTuple
(
Tuple
&
t
,
const
Functor
&
f
)
{
return
genericTransformTupleBackend
(
t
,
f
);
}
template
<
class
Tuple
,
class
Functor
>
typename
ForEachType
<
Functor
::
template
TypeEvaluator
,
Tuple
>
::
Type
genericTransformTuple
(
const
Tuple
&
t
,
const
Functor
&
f
)
{
return
genericTransformTupleBackend
(
t
,
f
);
}
#endif // ! defined(DOXYGEN)
namespace
{
template
<
int
i
,
typename
T1
,
typename
F
>
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment