@@ -61,12 +61,32 @@ 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 subscript assignment for std::string
71+ template <>
72+ inline typename r_vector<r_string>::proxy r_vector<r_string>::operator [](
73+ R_xlen_t i) const {
74+ return typename r_vector<r_string>::proxy (data_, i, nullptr , false );
75+ }
76+
77+ // Pacha: Optimized push_back for std::string
78+ template <>
79+ template <typename U, typename std::enable_if<std::is_same<U, r_string>::value>::type*>
80+ inline void r_vector<r_string>::push_back(const std::string& value) {
81+ while (this ->length_ >= this ->capacity_ ) {
82+ this ->reserve (this ->capacity_ == 0 ? 1 : this ->capacity_ * 2 );
83+ }
84+
85+ SEXP char_sexp = Rf_mkCharLenCE (value.c_str (), value.size (), CE_UTF8);
86+ SET_STRING_ELT (this ->data_ , this ->length_ , char_sexp);
87+ ++this ->length_ ;
88+ }
89+
7090inline bool operator ==(const r_vector<r_string>::proxy& lhs, r_string rhs) {
7191 return static_cast <r_string>(lhs).operator ==(static_cast <std::string>(rhs).c_str ());
7292}
@@ -95,17 +115,17 @@ inline SEXP alloc_if_charsxp(const SEXP data) {
95115
96116template <>
97117inline r_vector<r_string>::r_vector(const SEXP& data)
98- : cpp11::r_vector<r_string>(alloc_or_copy(data)), capacity_(length_) {
118+ : cpp11::r_vector<r_string>(alloc_or_copy(data)), capacity_(this -> length_) {
99119 if (detail::r_typeof (data) == CHARSXP) {
100- SET_STRING_ELT (data_, 0 , data);
120+ SET_STRING_ELT (this -> data_ , 0 , data);
101121 }
102122}
103123
104124template <>
105125inline r_vector<r_string>::r_vector(SEXP&& data)
106- : cpp11::r_vector<r_string>(alloc_if_charsxp(data)), capacity_(length_) {
126+ : cpp11::r_vector<r_string>(alloc_if_charsxp(data)), capacity_(this -> length_) {
107127 if (detail::r_typeof (data) == CHARSXP) {
108- SET_STRING_ELT (data_, 0 , data);
128+ SET_STRING_ELT (this -> data_ , 0 , data);
109129 }
110130}
111131
@@ -117,14 +137,15 @@ inline r_vector<r_string>::r_vector(std::initializer_list<r_string> il)
117137 unwind_protect ([&] {
118138 auto it = il.begin ();
119139
120- for (R_xlen_t i = 0 ; i < capacity_; ++i, ++it) {
140+ for (R_xlen_t i = 0 ; i < this -> capacity_ ; ++i, ++it) {
121141 // i.e. to `SEXP`
122- underlying_type elt = static_cast <underlying_type>(*it);
142+ typename r_vector<r_string>::underlying_type elt =
143+ static_cast <typename r_vector<r_string>::underlying_type>(*it);
123144
124145 if (elt == NA_STRING) {
125- set_elt (data_, i, elt);
146+ set_elt (this -> data_ , i, elt);
126147 } else {
127- set_elt (data_, i, Rf_mkCharCE (Rf_translateCharUTF8 (elt), CE_UTF8));
148+ set_elt (this -> data_ , i, Rf_mkCharCE (Rf_translateCharUTF8 (elt), CE_UTF8));
128149 }
129150 }
130151 });
@@ -135,12 +156,12 @@ typedef r_vector<r_string> strings;
135156template <typename T>
136157inline void r_vector<T>::push_back(const named_arg& value) {
137158 push_back (value.value ());
138- if (Rf_xlength (names ()) == 0 ) {
139- cpp11::writable::strings new_nms (size ());
140- names () = new_nms;
159+ if (Rf_xlength (this -> names ()) == 0 ) {
160+ cpp11::writable::strings new_nms (this -> size ());
161+ this -> names () = new_nms;
141162 }
142- cpp11::writable::strings nms (names ());
143- nms[size () - 1 ] = value.name ();
163+ cpp11::writable::strings nms (this -> names ());
164+ nms[this -> size () - 1 ] = value.name ();
144165}
145166
146167} // namespace writable
0 commit comments