Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
T
tnl-dev
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Model registry
Analyze
Value stream analytics
Contributor 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
This is an archived project. Repository and other project resources are read-only.
Show more breadcrumbs
TNL
tnl-dev
Commits
117edb17
There was an error fetching the commit references. Please try again later.
Commit
117edb17
authored
3 years ago
by
Tomáš Jakubec
Committed by
Jakub Klinkovský
3 years ago
Browse files
Options
Downloads
Patches
Plain Diff
Extension of the staticFor implementation
parent
ee53fa0a
No related branches found
No related tags found
1 merge request
!95
extension of the implementation of staticFor
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
Documentation/Examples/Algorithms/staticForExample.cpp
+48
-0
48 additions, 0 deletions
Documentation/Examples/Algorithms/staticForExample.cpp
src/TNL/Algorithms/staticFor.h
+37
-25
37 additions, 25 deletions
src/TNL/Algorithms/staticFor.h
with
85 additions
and
25 deletions
Documentation/Examples/Algorithms/staticForExample.cpp
+
48
−
0
View file @
117edb17
#include
<iostream>
#include
<array>
#include
<tuple>
#include
<TNL/Algorithms/staticFor.h>
/*
* Example function printing members of std::tuple using staticFor
* using lambda with capture.
*/
template
<
typename
...
Ts
>
void
printTuple
(
const
std
::
tuple
<
Ts
...
>&
tupleVar
)
{
std
::
cout
<<
"{ "
;
TNL
::
Algorithms
::
staticFor
<
size_t
,
0
,
sizeof
...
(
Ts
)
>
(
[
&
](
auto
i
)
{
std
::
cout
<<
std
::
get
<
i
>
(
tupleVar
);
if
(
i
<
sizeof
...
(
Ts
)
-
1
)
std
::
cout
<<
", "
;
});
std
::
cout
<<
" }"
<<
std
::
endl
;
}
struct
TuplePrinter
{
constexpr
TuplePrinter
()
=
default
;
template
<
typename
Index
,
typename
...
Ts
>
void
operator
()(
Index
i
,
const
std
::
tuple
<
Ts
...
>&
tupleVar
)
{
std
::
cout
<<
std
::
get
<
i
>
(
tupleVar
);
if
(
i
<
sizeof
...
(
Ts
)
-
1
)
std
::
cout
<<
", "
;
}
};
/*
* Example function printing members of std::tuple using staticFor
* and a structure with templated operator().
*/
template
<
typename
...
Ts
>
void
printTupleCallableStruct
(
const
std
::
tuple
<
Ts
...
>&
tupleVar
)
{
std
::
cout
<<
"{ "
;
TNL
::
Algorithms
::
staticFor
<
size_t
,
0
,
sizeof
...
(
Ts
)
>
(
TuplePrinter
(),
tupleVar
);
std
::
cout
<<
" }"
<<
std
::
endl
;
}
int
main
(
int
argc
,
char
*
argv
[]
)
{
// initiate std::array
...
...
@@ -13,4 +56,9 @@ int main( int argc, char* argv[] )
std
::
cout
<<
"a[ "
<<
i
<<
" ] = "
<<
std
::
get
<
i
>
(
a
)
<<
std
::
endl
;
}
);
// example of printing a tuple using staticFor and a lambda function
printTuple
(
std
::
make_tuple
(
"Hello"
,
3
,
2.1
)
);
// example of printing a tuple using staticFor and a structure with templated operator()
printTupleCallableStruct
(
std
::
make_tuple
(
"Hello"
,
3
,
2.1
)
);
}
This diff is collapsed.
Click to expand it.
src/TNL/Algorithms/staticFor.h
+
37
−
25
View file @
117edb17
...
...
@@ -27,20 +27,23 @@ static_for_dispatch( Func &&f )
#if __cplusplus >= 201703L
// C++17 version using fold expression
template
<
typename
Index
,
Index
begin
,
typename
Func
,
Index
...
idx
>
constexpr
void
static_for_impl
(
Func
&&
f
,
std
::
integer_sequence
<
Index
,
idx
...
>
)
template
<
typename
Index
,
Index
begin
,
typename
Func
,
Index
...
idx
,
typename
...
ArgTypes
>
constexpr
void
static_for_impl
(
Func
&&
f
,
std
::
integer_sequence
<
Index
,
idx
...
>
,
ArgTypes
&&
...
args
)
{
(
f
(
std
::
integral_constant
<
Index
,
begin
+
idx
>
{}
),
...
);
(
f
(
std
::
integral_constant
<
Index
,
begin
+
idx
>
{},
std
::
forward
<
ArgTypes
>
(
args
)...
),
...
);
}
// general dispatch for `begin < end`
template
<
typename
Index
,
Index
begin
,
Index
end
,
typename
Func
>
template
<
typename
Index
,
Index
begin
,
Index
end
,
typename
Func
,
typename
...
ArgTypes
>
constexpr
std
::
enable_if_t
<
(
begin
<
end
)
>
static_for_dispatch
(
Func
&&
f
)
static_for_dispatch
(
Func
&&
f
,
ArgTypes
&&
...
args
)
{
static_for_impl
<
Index
,
begin
>
(
std
::
forward
<
Func
>
(
f
),
std
::
make_integer_sequence
<
Index
,
end
-
begin
>
{}
std
::
make_integer_sequence
<
Index
,
end
-
begin
>
{},
std
::
forward
<
ArgTypes
>
(
args
)...
);
}
...
...
@@ -52,21 +55,24 @@ static_for_dispatch( Func &&f )
// the recursion depth.)
// special dispatch for 1 iteration
template
<
typename
Index
,
Index
begin
,
Index
end
,
typename
Func
>
template
<
typename
Index
,
Index
begin
,
Index
end
,
typename
Func
,
typename
...
ArgTypes
>
constexpr
std
::
enable_if_t
<
(
begin
<
end
&&
end
-
begin
==
1
)
>
static_for_dispatch
(
Func
&&
f
)
static_for_dispatch
(
Func
&&
f
,
ArgTypes
&&
...
args
)
{
f
(
std
::
integral_constant
<
Index
,
begin
>
{}
);
f
(
std
::
integral_constant
<
Index
,
begin
>
{},
std
::
forward
<
ArgTypes
>
(
args
)...
);
}
// general dispatch for at least 2 iterations
template
<
typename
Index
,
Index
begin
,
Index
end
,
typename
Func
>
template
<
typename
Index
,
Index
begin
,
Index
end
,
typename
Func
,
typename
...
ArgTypes
>
constexpr
std
::
enable_if_t
<
(
begin
<
end
&&
end
-
begin
>=
2
)
>
static_for_dispatch
(
Func
&&
f
)
static_for_dispatch
(
Func
&&
f
,
ArgTypes
&&
...
args
)
{
constexpr
Index
mid
=
begin
+
(
end
-
begin
)
/
2
;
static_for_dispatch
<
Index
,
begin
,
mid
>
(
std
::
forward
<
Func
>
(
f
)
);
static_for_dispatch
<
Index
,
mid
,
end
>
(
std
::
forward
<
Func
>
(
f
)
);
static_for_dispatch
<
Index
,
begin
,
mid
>
(
std
::
forward
<
Func
>
(
f
),
std
::
forward
<
ArgTypes
>
(
args
)...
);
static_for_dispatch
<
Index
,
mid
,
end
>
(
std
::
forward
<
Func
>
(
f
),
std
::
forward
<
ArgTypes
>
(
args
)...
);
}
#endif
...
...
@@ -79,34 +85,40 @@ static_for_dispatch( Func &&f )
*
* \e staticFor is a generic C++14/C++17 implementation of a static for-loop
* using \e constexpr functions and template metaprogramming. It is equivalent
* to executing a function `f(i)` for arguments `i` from the integral range
* `[begin, end)`, but with the type \ref std::integral_constant rather than
* `int` or `std::size_t` representing the indices. Hence, each index has its
* own distinct C++ type and the \e value of the index can be deduced from the
* type.
* to executing a function `f(i, args...)` for arguments `i` from the integral
* range `[begin, end)`, but with the type \ref std::integral_constant rather
* than `int` or `std::size_t` representing the indices. Hence, each index has
* its own distinct C++ type and the \e value of the index can be deduced from
* the type. The `args...` are additional user-supplied arguments that are
* forwarded to the \e staticFor function.
*
* Also note that thanks to `constexpr`, the argument `i` can be
used in
* constant expressions and the \e staticFor function can be used from
the host
* code as well as CUDA kernels (TNL requires the
`--expt-relaxed-constexpr`
* parameter when compiled by `nvcc`).
* Also note that thanks to `constexpr`
cast operator
, the argument `i` can be
*
used in
constant expressions and the \e staticFor function can be used from
*
the host
code as well as CUDA kernels (TNL requires the
*
`--expt-relaxed-constexpr`
parameter when compiled by `nvcc`).
*
* \tparam Index is the type of the loop indices.
* \tparam begin is the left bound of the iteration range `[begin, end)`.
* \tparam end is the right bound of the iteration range `[begin, end)`.
* \tparam Func is the type of the functor (it is usually deduced from the
* argument used in the function call).
* \tparam ArgTypes are the types of additional arguments passed to the
* function.
*
* \param f is the functor to be called in each iteration.
* \param args... are additional user-supplied arguments that are forwarded
* to each call of \e f.
*
* \par Example
* \include Algorithms/staticForExample.cpp
* \par Output
* \include staticForExample.out
*/
template
<
typename
Index
,
Index
begin
,
Index
end
,
typename
Func
>
constexpr
void
staticFor
(
Func
&&
f
)
template
<
typename
Index
,
Index
begin
,
Index
end
,
typename
Func
,
typename
...
ArgTypes
>
constexpr
void
staticFor
(
Func
&&
f
,
ArgTypes
&&
...
args
)
{
detail
::
static_for_dispatch
<
Index
,
begin
,
end
>
(
std
::
forward
<
Func
>
(
f
)
);
detail
::
static_for_dispatch
<
Index
,
begin
,
end
>
(
std
::
forward
<
Func
>
(
f
),
std
::
forward
<
ArgTypes
>
(
args
)...
);
}
}
// namespace Algorithms
...
...
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