-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathDottedPairImpl.h
More file actions
106 lines (88 loc) · 3.21 KB
/
DottedPairImpl.h
File metadata and controls
106 lines (88 loc) · 3.21 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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#ifndef Rcpp_DottedPairImpl_h
#define Rcpp_DottedPairImpl_h
namespace Rcpp{
template <typename CLASS>
class DottedPairImpl {
public:
template <typename T>
Node push_front( const T& object){
CLASS& ref = get_ref() ;
ref.set__( grow(object, ref.get__() ) ) ;
return Node(ref.get__()) ;
}
template <typename T>
Node push_back( const T& object) {
CLASS& ref = get_ref() ;
if( ref.isNULL() ){
ref.set__( grow( object, ref.get__() ) ) ;
return Node( ref.get__() );
} else {
SEXP x = ref.get__() ;
/* traverse the pairlist */
while( !Rf_isNull(CDR(x)) ){
x = CDR(x) ;
}
Shield<SEXP> tail = pairlist( object ) ;
SETCDR( x, tail ) ;
return Node(tail) ;
}
}
template <typename T>
Node insert( const size_t& index, const T& object) {
CLASS& ref = get_ref() ;
if( index == 0 ) {
return push_front( object ) ;
} else {
if( ref.isNULL( ) ) throw index_out_of_bounds() ;
if( static_cast<R_len_t>(index) > ::Rf_length(ref.get__()) ) throw index_out_of_bounds() ;
size_t i=1;
SEXP x = ref.get__() ;
while( i < index ){
x = CDR(x) ;
i++;
}
Shield<SEXP> tail = grow( object, CDR(x) ) ;
SETCDR( x, tail ) ;
return Node(tail) ;
}
}
template <typename T>
Node replace( const int& index, const T& object ) {
CLASS& ref = get_ref() ;
if( static_cast<R_len_t>(index) >= ::Rf_length(ref.get__()) ) throw index_out_of_bounds() ;
Shield<SEXP> x = pairlist( object );
SEXP y = ref.get__() ;
int i=0;
while( i<index ){ y = CDR(y) ; i++; }
SETCAR( y, CAR(x) );
SET_TAG( y, TAG(x) );
return Node(y) ;
}
inline R_len_t length() const {
return ::Rf_length(get_ref().get__()) ;
}
inline R_len_t size() const {
return length() ;
}
void remove( const size_t& index ){
CLASS& ref = static_cast<CLASS&>(*this) ;
if( static_cast<R_len_t>(index) >= Rf_length(ref.get__()) ) throw index_out_of_bounds() ;
if( index == 0 ){
ref.set__( CDR( ref.get__() ) ) ;
} else{
SEXP x = ref.get__() ;
size_t i=1;
while( i<index ){ x = CDR(x) ; i++; }
SETCDR( x, CDDR(x) ) ;
}
}
private:
CLASS& get_ref(){
return static_cast<CLASS&>(*this) ;
}
const CLASS& get_ref() const {
return static_cast<const CLASS&>(*this) ;
}
} ;
}
#endif