|
2 | 2 | #define dplyr_Result_Min_H
|
3 | 3 |
|
4 | 4 | namespace dplyr {
|
5 |
| - |
| 5 | + |
6 | 6 | template <int RTYPE, bool NA_RM>
|
7 | 7 | class Min : public Processor<RTYPE, Min<RTYPE,NA_RM> > {
|
8 | 8 | public:
|
9 | 9 | typedef Processor<RTYPE, Min<RTYPE,NA_RM> > Base ;
|
10 | 10 | typedef typename Rcpp::traits::storage_type<RTYPE>::type STORAGE ;
|
11 |
| - |
12 |
| - Min(SEXP x, bool is_summary_ = false) : |
13 |
| - Base(x), |
14 |
| - data_ptr( Rcpp::internal::r_vector_start<RTYPE>(x) ), |
15 |
| - is_summary(is_summary_) |
| 11 | + |
| 12 | + Min(SEXP x, bool is_summary_ = false) : |
| 13 | + Base(x), |
| 14 | + data_ptr( Rcpp::internal::r_vector_start<RTYPE>(x) ), |
| 15 | + is_summary(is_summary_) |
16 | 16 | {}
|
17 | 17 | ~Min(){}
|
18 |
| - |
| 18 | + |
19 | 19 | STORAGE process_chunk( const SlicingIndex& indices ){
|
| 20 | + if( indices.size() == 0) return R_PosInf ; |
20 | 21 | if( is_summary ) return data_ptr[ indices.group() ] ;
|
21 |
| - |
| 22 | + |
22 | 23 | int n = indices.size() ;
|
23 | 24 | // find the first non NA value
|
24 | 25 | STORAGE res = data_ptr[ indices[0] ] ;
|
25 | 26 | int i=1 ;
|
26 | 27 | while( i<n && Rcpp::Vector<RTYPE>::is_na(res) ){
|
27 |
| - res = data_ptr[ indices[i++] ] ; |
| 28 | + res = data_ptr[ indices[i++] ] ; |
28 | 29 | }
|
29 |
| - |
| 30 | + |
30 | 31 | // we enter this loop if we did not scan the full vector
|
31 | 32 | if( i < n ) for( ; i<n; i++){
|
32 | 33 | STORAGE current = data_ptr[indices[i]] ;
|
33 | 34 | if( !Rcpp::Vector<RTYPE>::is_na(current) && internal::is_smaller<RTYPE>( current, res ) ) res = current ;
|
34 | 35 | }
|
35 |
| - |
| 36 | + |
36 | 37 | return res ;
|
37 | 38 | }
|
38 |
| - |
| 39 | + |
39 | 40 | private:
|
40 | 41 | STORAGE* data_ptr ;
|
41 | 42 | bool is_summary ;
|
42 | 43 | } ;
|
43 |
| - |
| 44 | + |
44 | 45 | // quit early version for NA_RM = false
|
45 | 46 | template <int RTYPE>
|
46 | 47 | class Min<RTYPE,false> : public Processor<RTYPE, Min<RTYPE,false> > {
|
47 | 48 | public:
|
48 |
| - typedef Processor<RTYPE, Min<RTYPE,false> > Base ; |
| 49 | + typedef Processor<RTYPE, Min<RTYPE,false> > Base ; |
49 | 50 | typedef typename Rcpp::traits::storage_type<RTYPE>::type STORAGE ;
|
50 |
| - |
51 |
| - Min(SEXP x, bool is_summary_ = false) : |
52 |
| - Base(x), |
53 |
| - data_ptr( Rcpp::internal::r_vector_start<RTYPE>(x) ), |
54 |
| - is_summary(is_summary_) |
| 51 | + |
| 52 | + Min(SEXP x, bool is_summary_ = false) : |
| 53 | + Base(x), |
| 54 | + data_ptr( Rcpp::internal::r_vector_start<RTYPE>(x) ), |
| 55 | + is_summary(is_summary_) |
55 | 56 | {}
|
56 | 57 | ~Min(){}
|
57 |
| - |
| 58 | + |
58 | 59 | STORAGE process_chunk( const SlicingIndex& indices ){
|
| 60 | + if( indices.size() == 0) return R_PosInf ; |
59 | 61 | if( is_summary ) return data_ptr[ indices.group() ] ;
|
60 |
| - |
| 62 | + |
61 | 63 | int n = indices.size() ;
|
62 |
| - |
| 64 | + |
63 | 65 | // find the first non NA value
|
64 | 66 | STORAGE res = data_ptr[ indices[0] ] ;
|
65 | 67 | if( Rcpp::Vector<RTYPE>::is_na(res) ) return res;
|
66 |
| - |
| 68 | + |
67 | 69 | for( int i=1; i<n; i++){
|
68 | 70 | STORAGE current = data_ptr[indices[i]] ;
|
69 | 71 | if( Rcpp::Vector<RTYPE>::is_na(current) ) return current ;
|
70 | 72 | if( internal::is_smaller<RTYPE>( current, res ) ) res = current ;
|
71 | 73 | }
|
72 | 74 | return res ;
|
73 | 75 | }
|
74 |
| - |
| 76 | + |
75 | 77 | private:
|
76 |
| - STORAGE* data_ptr ; |
| 78 | + STORAGE* data_ptr ; |
77 | 79 | bool is_summary ;
|
78 | 80 | } ;
|
79 |
| - |
80 |
| - |
| 81 | + |
| 82 | + |
81 | 83 | }
|
82 | 84 |
|
83 | 85 | #endif
|
0 commit comments