@@ -61,12 +61,24 @@ typedef r_vector<r_string> strings;
6161namespace writable {
6262
6363template <>
64- inline void r_vector<r_string>::set_elt(SEXP x, R_xlen_t i,
65- typename r_vector::underlying_type value) {
64+ inline void r_vector<r_string>::set_elt(
65+ SEXP x, R_xlen_t i, typename r_vector<r_string> ::underlying_type value) {
6666 // NOPROTECT: Likely too costly to unwind protect every set elt
6767 SET_STRING_ELT (x, i, value);
6868}
6969
70+ // Pacha: Optimized push_back for std::string (borrows from @traversc' push_back_fast)
71+ template <>
72+ template <typename U, typename std::enable_if<std::is_same<U, r_string>::value>::type*>
73+ inline void r_vector<r_string>::push_back(const std::string& value) {
74+ while (this ->length_ >= this ->capacity_ ) {
75+ this ->reserve (this ->capacity_ == 0 ? 1 : this ->capacity_ * 2 );
76+ }
77+ set_elt (this ->data_ , this ->length_ ,
78+ Rf_mkCharLenCE (value.c_str (), value.size (), CE_UTF8));
79+ ++this ->length_ ;
80+ }
81+
7082inline bool operator ==(const r_vector<r_string>::proxy& lhs, r_string rhs) {
7183 return static_cast <r_string>(lhs).operator ==(static_cast <std::string>(rhs).c_str ());
7284}
@@ -95,17 +107,17 @@ inline SEXP alloc_if_charsxp(const SEXP data) {
95107
96108template <>
97109inline r_vector<r_string>::r_vector(const SEXP& data)
98- : cpp11::r_vector<r_string>(alloc_or_copy(data)), capacity_(length_) {
110+ : cpp11::r_vector<r_string>(alloc_or_copy(data)), capacity_(this -> length_) {
99111 if (detail::r_typeof (data) == CHARSXP) {
100- SET_STRING_ELT (data_, 0 , data);
112+ SET_STRING_ELT (this -> data_ , 0 , data);
101113 }
102114}
103115
104116template <>
105117inline r_vector<r_string>::r_vector(SEXP&& data)
106- : cpp11::r_vector<r_string>(alloc_if_charsxp(data)), capacity_(length_) {
118+ : cpp11::r_vector<r_string>(alloc_if_charsxp(data)), capacity_(this -> length_) {
107119 if (detail::r_typeof (data) == CHARSXP) {
108- SET_STRING_ELT (data_, 0 , data);
120+ SET_STRING_ELT (this -> data_ , 0 , data);
109121 }
110122}
111123
@@ -117,14 +129,15 @@ inline r_vector<r_string>::r_vector(std::initializer_list<r_string> il)
117129 unwind_protect ([&] {
118130 auto it = il.begin ();
119131
120- for (R_xlen_t i = 0 ; i < capacity_; ++i, ++it) {
132+ for (R_xlen_t i = 0 ; i < this -> capacity_ ; ++i, ++it) {
121133 // i.e. to `SEXP`
122- underlying_type elt = static_cast <underlying_type>(*it);
134+ typename r_vector<r_string>::underlying_type elt =
135+ static_cast <typename r_vector<r_string>::underlying_type>(*it);
123136
124137 if (elt == NA_STRING) {
125- set_elt (data_, i, elt);
138+ set_elt (this -> data_ , i, elt);
126139 } else {
127- set_elt (data_, i, Rf_mkCharCE (Rf_translateCharUTF8 (elt), CE_UTF8));
140+ set_elt (this -> data_ , i, Rf_mkCharCE (Rf_translateCharUTF8 (elt), CE_UTF8));
128141 }
129142 }
130143 });
@@ -135,12 +148,12 @@ typedef r_vector<r_string> strings;
135148template <typename T>
136149inline void r_vector<T>::push_back(const named_arg& value) {
137150 push_back (value.value ());
138- if (Rf_xlength (names ()) == 0 ) {
139- cpp11::writable::strings new_nms (size ());
140- names () = new_nms;
151+ if (Rf_xlength (this -> names ()) == 0 ) {
152+ cpp11::writable::strings new_nms (this -> size ());
153+ this -> names () = new_nms;
141154 }
142- cpp11::writable::strings nms (names ());
143- nms[size () - 1 ] = value.name ();
155+ cpp11::writable::strings nms (this -> names ());
156+ nms[this -> size () - 1 ] = value.name ();
144157}
145158
146159} // namespace writable
0 commit comments