Skip to content

Commit 08778ed

Browse files
committed
more forwarding
1 parent 968e345 commit 08778ed

File tree

4 files changed

+83
-25
lines changed

4 files changed

+83
-25
lines changed

gen/nt2-functors.R

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,44 +34,52 @@ template <- paste(c(
3434

3535
code <- NULL
3636

37-
# NOTE: Each function should accept a parameter called 'data'.
3837
unary <- list(
39-
sum = "return sum(data);"
38+
sum = c("sum(std::forward<T>(t))", "return sum(std::forward<T>(t));"),
39+
size = c("std::forward<T>(t).size()", "return std::forward<T>(t).size();")
4040
)
4141

4242
unary_template <- paste(c(
4343
"struct %s {",
4444
"template <typename T>",
45-
"inline T operator()(const T& data) {",
45+
"inline auto operator()(T&& t) -> decltype(%s)",
46+
"{",
4647
"%s",
4748
"}",
4849
"};",
4950
""
5051
), collapse = "\n")
5152

5253
forEach(unary, function(name, value) {
53-
code <<- c(code, sprintf(unary_template, name, indent(value)))
54+
code <<- c(code, sprintf(unary_template, name, value[[1]], indent(value[[2]])))
5455
})
5556

57+
binary_code <- function(op) {
58+
forwarded <- sprintf("std::forward<%s>(%s)", c("T", "U"), c("t", "u"))
59+
pasted <- paste(forwarded, collapse = op)
60+
c(pasted, sprintf("return %s;", pasted))
61+
}
62+
5663
binary <- list(
57-
plus = "return lhs + rhs;",
58-
minus = "return lhs - rhs;",
59-
times = "return lhs * rhs;",
60-
divide = "return lhs / rhs;"
64+
plus = binary_code(" + "),
65+
minus = binary_code(" - "),
66+
times = binary_code(" * "),
67+
divide = binary_code(" / ")
6168
)
6269

6370
binary_template <- paste(c(
6471
"struct %s {",
65-
"template <typename T>",
66-
"inline T operator()(const T& lhs, const T& rhs) {",
72+
"template <typename T, typename U>",
73+
"inline auto operator()(T&& t, U&& u) -> decltype(%s)",
74+
"{",
6775
"%s",
6876
"}",
6977
"};",
7078
""
7179
), collapse = "\n")
7280

7381
forEach(binary, function(name, value) {
74-
code <<- c(code, sprintf(binary_template, name, indent(value)))
82+
code <<- c(code, sprintf(binary_template, name, value[[1]], indent(value[[2]])))
7583
})
7684

7785
compiled <- sprintf(template, paste(code, collapse = "\n"))

inst/include/RcppNT2.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,6 @@
4141

4242
#include <RcppNT2/algorithm.h>
4343
#include <RcppNT2/functor.h>
44+
#include <RcppNT2/variadic.h>
4445

4546
#endif /* RCPP_NT2_H */

inst/include/RcppNT2/functor.h

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,36 +9,49 @@ namespace functor {
99

1010
struct sum {
1111
template <typename T>
12-
inline T operator()(const T& data) {
13-
return sum(data);
12+
inline auto operator()(T&& t) -> decltype(sum(std::forward<T>(t)))
13+
{
14+
return sum(std::forward<T>(t));
1415
}
1516
};
1617

17-
struct plus {
18+
struct size {
1819
template <typename T>
19-
inline T operator()(const T& lhs, const T& rhs) {
20-
return lhs + rhs;
20+
inline auto operator()(T&& t) -> decltype(std::forward<T>(t).size())
21+
{
22+
return std::forward<T>(t).size();
23+
}
24+
};
25+
26+
struct plus {
27+
template <typename T, typename U>
28+
inline auto operator()(T&& t, U&& u) -> decltype(std::forward<T>(t) + std::forward<U>(u))
29+
{
30+
return std::forward<T>(t) + std::forward<U>(u);
2131
}
2232
};
2333

2434
struct minus {
25-
template <typename T>
26-
inline T operator()(const T& lhs, const T& rhs) {
27-
return lhs - rhs;
35+
template <typename T, typename U>
36+
inline auto operator()(T&& t, U&& u) -> decltype(std::forward<T>(t) - std::forward<U>(u))
37+
{
38+
return std::forward<T>(t) - std::forward<U>(u);
2839
}
2940
};
3041

3142
struct times {
32-
template <typename T>
33-
inline T operator()(const T& lhs, const T& rhs) {
34-
return lhs * rhs;
43+
template <typename T, typename U>
44+
inline auto operator()(T&& t, U&& u) -> decltype(std::forward<T>(t) * std::forward<U>(u))
45+
{
46+
return std::forward<T>(t) * std::forward<U>(u);
3547
}
3648
};
3749

3850
struct divide {
39-
template <typename T>
40-
inline T operator()(const T& lhs, const T& rhs) {
41-
return lhs / rhs;
51+
template <typename T, typename U>
52+
inline auto operator()(T&& t, U&& u) -> decltype(std::forward<T>(t) / std::forward<U>(u))
53+
{
54+
return std::forward<T>(t) / std::forward<U>(u);
4255
}
4356
};
4457

inst/include/RcppNT2/variadic.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#ifndef RCPP_NT2_VARIADIC_H
2+
#define RCPP_NT2_VARIADIC_H
3+
4+
namespace RcppNT2 {
5+
namespace variadic {
6+
7+
template <typename F, typename... Args>
8+
inline auto apply(F&& f, Args&&... args) -> decltype(std::forward<F>(f)(std::forward<Args>(args)...))
9+
{
10+
return std::forward<F>(f)(std::forward<Args>(args)...);
11+
}
12+
13+
template <typename F, typename T>
14+
inline auto min(F&& f, T&& t) -> decltype(std::forward<T>(t))
15+
{
16+
return std::forward<T>(t);
17+
}
18+
19+
template <typename F, typename T, typename... Ts>
20+
inline auto min(F&& f, T&& t, Ts&&... ts) -> decltype(std::forward<T>(t))
21+
{
22+
return (min(std::forward<F>(f), std::forward<T>(t)) < min(std::forward<F>(f), std::forward<Ts>(ts)...))
23+
? min(std::forward<F>(f), std::forward<T>(t))
24+
: min(std::forward<F>(f), std::forward<Ts>(ts)...);
25+
}
26+
27+
template <int Index, typename... Ts>
28+
std::size_t size(Ts&&... ts)
29+
{
30+
return std::get<Index>(std::tuple<Ts...>()).size();
31+
}
32+
33+
} // namespace variadic
34+
} // namespace RcppNT2
35+
36+
#endif /* RCPP_NT2_VARIADIC_H */

0 commit comments

Comments
 (0)