-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathIndex.h
More file actions
63 lines (46 loc) · 1.64 KB
/
Index.h
File metadata and controls
63 lines (46 loc) · 1.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#ifndef Rcpp__Index__h
#define Rcpp__Index__h
namespace Rcpp{
template <int N, typename... Args>
constexpr bool ValidIndexArgs() {
return traits::and_<std::is_convertible<Args, size_t>...>::value && (N == sizeof...(Args) ) ;
}
template <int N>
class Index {
public:
Index(){}
template <
typename... Args,
typename = typename std::enable_if< ValidIndexArgs<N,Args...>() >::type
>
Index( Args... args ) : dimensions({ static_cast<size_t>(args)... }) {}
template <
typename... Args,
typename = typename std::enable_if< ValidIndexArgs<N,Args...>() >::type
>
size_t operator()( Args... args){
return get_index( args... ) ;
}
inline size_t prod(){
return std::accumulate( begin(dimensions), end(dimensions), 1, std::multiplies<double>() ) ;
}
inline size_t size(){
return N ;
}
inline operator SEXP() const { return wrap( dimensions ); }
inline operator SEXP() { return wrap( dimensions ); }
inline size_t& operator[](int i){
return dimensions[i] ;
}
private:
template <typename... Args >
size_t get_index( size_t first, Args... args){
return first + dimensions[ N - sizeof...(Args) - 1 ] * get_index( args... );
}
size_t get_index( size_t first ){
return first ;
}
std::array<size_t,N> dimensions ;
} ;
} // Rcpp
#endif