2323#define Rcpp__DataFrame_h
2424
2525namespace Rcpp {
26-
26+
2727 namespace internal {
2828 inline SEXP empty_data_frame (){
2929 Shield<SEXP> df ( Rf_allocVector (VECSXP, 0 ) );
@@ -33,33 +33,39 @@ namespace Rcpp{
3333 return df;
3434 }
3535 }
36-
36+
3737 template <template <class > class StoragePolicy >
3838 class DataFrame_Impl : public Vector <VECSXP, StoragePolicy> {
39- public:
39+ public:
4040 typedef Vector<VECSXP, StoragePolicy> Parent ;
41-
41+
4242 DataFrame_Impl () : Parent( internal::empty_data_frame() ){}
4343 DataFrame_Impl (SEXP x) {
44- set__ (x);
44+ set__ (x);
4545 }
4646 DataFrame_Impl ( const DataFrame_Impl& other){
47- set__ (other) ;
47+ set__ (other) ;
4848 }
49-
49+
5050 template <typename T>
5151 DataFrame_Impl ( const T& obj ) ;
52-
52+
5353 DataFrame_Impl& operator =( DataFrame_Impl& other){
54- if (*this != other) set__ (other);
54+ if (*this != other) set__ (other);
5555 return *this ;
5656 }
57-
57+
5858 DataFrame_Impl& operator =( SEXP x){
5959 set__ (x) ;
6060 return *this ;
6161 }
62-
62+
63+ // By definition, the number of rows in a data.frame is contained
64+ // in its row.names attribute. If it has row names of the form 1:n,
65+ // they will be stored as {NA_INTEGER, -<nrow>}. Unfortunately,
66+ // getAttrib(df, R_RowNamesSymbol) will force an expansion of that
67+ // compact form thereby allocating a huge vector when we just want
68+ // the row.names. Hence this workaround.
6369 inline int nrows () const {
6470 SEXP rn = R_NilValue ;
6571 SEXP att = ATTRIB ( Parent::get__ () ) ;
@@ -68,20 +74,20 @@ namespace Rcpp{
6874 rn = CAR (att) ;
6975 break ;
7076 }
71- att = CDR (att) ;
77+ att = CDR (att) ;
7278 }
7379 if (Rf_isNull (rn))
7480 return 0 ;
7581 if (TYPEOF (rn) == INTSXP && LENGTH (rn) == 2 && INTEGER (rn)[0 ] == NA_INTEGER)
7682 return -INTEGER (rn)[1 ];
7783 return LENGTH (rn);
7884 }
79-
80- static DataFrame_Impl create (){
81- return DataFrame_Impl () ;
85+
86+ static DataFrame_Impl create (){
87+ return DataFrame_Impl () ;
8288 }
8389
84- #include < Rcpp/generated/DataFrame_generated.h>
90+ #include < Rcpp/generated/DataFrame_generated.h>
8591
8692 private:
8793 void set__ (SEXP x){
@@ -92,7 +98,7 @@ namespace Rcpp{
9298 Parent::set__ ( y ) ;
9399 }
94100 }
95-
101+
96102 static DataFrame_Impl from_list ( Parent obj ){
97103 bool use_default_strings_as_factors = true ;
98104 bool strings_as_factors = true ;
@@ -103,30 +109,30 @@ namespace Rcpp{
103109 for ( int i=0 ; i<n; i++){
104110 if ( names[i] == " stringsAsFactors" ){
105111 strings_as_factors_index = i ;
106- use_default_strings_as_factors = false ;
112+ use_default_strings_as_factors = false ;
107113 if ( !as<bool >(obj[i]) ) strings_as_factors = false ;
108- break ;
114+ break ;
109115 }
110116 }
111117 }
112- if ( use_default_strings_as_factors )
118+ if ( use_default_strings_as_factors )
113119 return DataFrame_Impl (obj) ;
114120 SEXP as_df_symb = Rf_install (" as.data.frame" );
115121 SEXP strings_as_factors_symb = Rf_install (" stringsAsFactors" );
116-
122+
117123 obj.erase (strings_as_factors_index) ;
118124 names.erase (strings_as_factors_index) ;
119125 obj.attr ( " names" ) = names ;
120126 Shield<SEXP> call ( Rf_lang3 (as_df_symb, obj, wrap ( strings_as_factors ) ) ) ;
121- SET_TAG ( CDDR (call), strings_as_factors_symb ) ;
122- Shield<SEXP> res ( Rcpp_eval ( call ) ) ;
127+ SET_TAG ( CDDR (call), strings_as_factors_symb ) ;
128+ Shield<SEXP> res ( Rcpp_eval ( call ) ) ;
123129 DataFrame_Impl out ( res ) ;
124130 return out ;
125-
131+
126132 }
127-
133+
128134 } ;
129-
135+
130136 typedef DataFrame_Impl<PreserveStorage> DataFrame ;
131137}
132138
0 commit comments