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
bfb15475
Commit
bfb15475
authored
Nov 29, 2020
by
Praetorius, Simon
Browse files
add enumerate algorithm andremove exclusive_scan
parent
f9a94a4e
Changes
1
Hide whitespace changes
Inline
Side-by-side
amdis/common/Algorithm.hpp
View file @
bfb15475
...
...
@@ -2,66 +2,71 @@
#include <algorithm>
#include <functional>
#include <iterator>
#include <tuple>
#include <type_traits>
#include <utility>
namespace
AMDiS
namespace
AMDiS
{
/// \brief Split a sequence `[first,last)` by the separators `sep` and pass the tokens as
/// begin-end iterator pair to the provided functor `f = void(InputIterator, InputIterator)`
template
<
class
InputIter
,
class
Tp
,
class
BinaryFunc
>
void
split
(
InputIter
first
,
InputIter
last
,
Tp
sep
,
BinaryFunc
f
)
{
/// \brief Split a sequence `[first,last)` by the separators `sep` and pass the tokens as
/// begin-end iterator pair to the provided functor `f = void(InputIterator, InputIterator)`
template
<
class
InputIter
,
class
Tp
,
class
BinaryFunc
>
void
split
(
InputIter
first
,
InputIter
last
,
Tp
sep
,
BinaryFunc
f
)
{
if
(
first
==
last
)
return
;
if
(
first
==
last
)
return
;
while
(
true
)
{
InputIter
found
=
std
::
find
(
first
,
last
,
sep
);
f
(
first
,
found
);
if
(
found
==
last
)
break
;
first
=
++
found
;
}
while
(
true
)
{
InputIter
found
=
std
::
find
(
first
,
last
,
sep
);
f
(
first
,
found
);
if
(
found
==
last
)
break
;
first
=
++
found
;
}
}
/// \brief Split a sequence `[first,last)` by any of the separators `[s_first, s_last)` and pass the tokens as
/// begin-end iterator pair to the provided functor `f = void(InputIterator, InputIterator)`
template
<
class
InputIter
,
class
SeparaterIter
,
class
BinaryFunc
>
void
split
(
InputIter
first
,
InputIter
last
,
SeparaterIter
s_first
,
SeparaterIter
s_last
,
BinaryFunc
f
)
{
if
(
first
==
last
)
return
;
/// \brief Split a sequence `[first,last)` by any of the separators `[s_first, s_last)` and pass the tokens as
/// begin-end iterator pair to the provided functor `f = void(InputIterator, InputIterator)`
template
<
class
InputIter
,
class
SeparaterIter
,
class
BinaryFunc
>
void
split
(
InputIter
first
,
InputIter
last
,
SeparaterIter
s_first
,
SeparaterIter
s_last
,
BinaryFunc
f
)
{
if
(
first
==
last
)
return
;
while
(
true
)
{
InputIter
found
=
std
::
find_first_of
(
first
,
last
,
s_first
,
s_last
);
f
(
first
,
found
);
if
(
found
==
last
)
break
;
first
=
++
found
;
}
while
(
true
)
{
InputIter
found
=
std
::
find_first_of
(
first
,
last
,
s_first
,
s_last
);
f
(
first
,
found
);
if
(
found
==
last
)
break
;
first
=
++
found
;
}
}
/// \brief Output the cumulative sum of one range to a second range
// NOTE: backport of std::exclusive_scan from c++17
template
<
class
InputIter
,
class
OutputIter
,
class
Tp
,
class
BinaryOperation
>
OutputIter
exclusive_scan
(
InputIter
first
,
InputIter
last
,
OutputIter
result
,
Tp
init
,
BinaryOperation
binary_op
)
/// \brief Provide python-like indexing iterator that returns a pair of [i,element]
// see: http://reedbeta.com/blog/python-like-enumerate-in-cpp17
template
<
class
Range
,
class
Iter
=
decltype
(
std
::
begin
(
std
::
declval
<
Range
>())),
class
=
decltype
(
std
::
end
(
std
::
declval
<
Range
>
()))
>
constexpr
auto
enumerate
(
Range
&&
range
)
{
struct
iterator
{
while
(
first
!=
last
)
{
auto
v
=
init
;
init
=
binary_op
(
init
,
*
first
);
++
first
;
*
result
++
=
std
::
move
(
v
);
}
return
result
;
}
typename
std
::
iterator_traits
<
Iter
>::
difference_type
i
;
Iter
iter
;
bool
operator
!=
(
iterator
const
&
other
)
const
{
return
iter
!=
other
.
iter
;
}
void
operator
++
()
{
++
i
;
++
iter
;
}
auto
operator
*
()
const
{
return
std
::
tie
(
i
,
*
iter
);
}
};
/// \brief Output the cumulative sum of one range to a second range
// NOTE: backport of std::exclusive_scan from c++17
template
<
class
InputIter
,
class
OutputIter
,
class
Tp
>
inline
OutputIter
exclusive_scan
(
InputIter
first
,
InputIter
last
,
OutputIter
result
,
Tp
init
)
struct
range_wrapper
{
return
AMDiS
::
exclusive_scan
(
first
,
last
,
result
,
std
::
move
(
init
),
std
::
plus
<>
());
}
Range
range
;
auto
begin
()
{
return
iterator
{
0
,
std
::
begin
(
range
)};
}
auto
end
()
{
return
iterator
{
0
,
std
::
end
(
range
)};
}
};
return
range_wrapper
{
std
::
forward
<
Range
>
(
range
)};
}
}
\ No newline at end of file
}
// end namepace AMDiS
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment