@@ -58,8 +58,11 @@ namespace Rcpp {
5858 }
5959
6060 /* * copy constructor */
61- String (const String& other) : data(other.get_sexp()), token(R_NilValue), valid(true ), buffer_ready(false ), enc(Rf_getCharCE(other.get_sexp())) {
62- token = Rcpp_PreciousPreserve (data);
61+ String (const String& s) : data(R_NilValue), token(R_NilValue), buffer(s.buffer), valid(s.valid), buffer_ready(s.buffer_ready), enc(s.enc) {
62+ if (!buffer_ready) {
63+ data = s.get_sexp ();
64+ token = Rcpp_PreciousPreserve (data);
65+ }
6366 RCPP_STRING_DEBUG (" String(const String&)" );
6467 }
6568
@@ -111,12 +114,27 @@ namespace Rcpp {
111114 }
112115
113116 /* * from a std::string */
114- String (const std::string& s, cetype_t enc = CE_UTF8) : buffer(s), valid(false ), buffer_ready(true ), enc(enc) {
115- data = R_NilValue;
116- token = R_NilValue;
117+ String (const std::string& s, cetype_t enc = CE_UTF8) : data(R_NilValue), token(R_NilValue), buffer(s), valid(false ), buffer_ready(true ), enc(enc) {
117118 RCPP_STRING_DEBUG (" String(const std::string&, cetype_t)" );
118119 }
120+ #ifdef RCPP_USING_CXX11
121+ /* * move constructor */
122+ String (String&& s) : data(s.data), token(s.token), buffer(std::move(s.buffer)), valid(s.valid), buffer_ready(s.buffer_ready), enc(s.enc) {
123+ // Erase s.
124+ s.data = R_NilValue;
125+ s.token = R_NilValue;
126+ s.buffer = std::string ();
127+ s.valid = false ;
128+ s.buffer_ready = true ;
129+ s.enc = CE_UTF8;
130+ RCPP_STRING_DEBUG (" String(String&&)" );
131+ }
119132
133+ /* * move a std::string */
134+ String (std::string&& s, cetype_t enc = CE_UTF8) : data(R_NilValue), token(R_NilValue), buffer(s), valid(false ), buffer_ready(true ), enc(enc) {
135+ RCPP_STRING_DEBUG (" String(std::string&&, cetype_t)" );
136+ }
137+ #endif
120138 String (const std::wstring& s, cetype_t enc = CE_UTF8) : data(internal::make_charsexp(s)), token(R_NilValue), valid(true ), buffer_ready(false ), enc(enc) {
121139 token = Rcpp_PreciousPreserve (data);
122140 RCPP_STRING_DEBUG (" String(const std::wstring&, cetype_t)" );
@@ -220,14 +238,27 @@ namespace Rcpp {
220238 return *this ;
221239 }
222240 inline String& operator =(const String& other) {
223- SEXP x = other.get_sexp ();
224- if (data != x) {
225- data = x;
226- Rcpp_PreciousRelease (token);
227- token = Rcpp_PreciousPreserve (x);
241+ if (other.buffer_ready ) {
242+ // Copy the buffer without creating a SEXP.
243+ if (valid) {
244+ Rcpp_PreciousRelease (token);
245+ valid = false ;
246+ }
247+ data = R_NilValue;
248+ token = R_NilValue;
249+ buffer = other.buffer ;
250+ buffer_ready = true ;
251+ enc = other.enc ;
252+ } else {
253+ SEXP x = other.get_sexp ();
254+ if (data != x) {
255+ data = x;
256+ Rcpp_PreciousRelease (token);
257+ token = Rcpp_PreciousPreserve (x);
258+ }
259+ valid = true ;
260+ buffer_ready = false ;
228261 }
229- valid = true ;
230- buffer_ready = false ;
231262 return *this ;
232263 }
233264 inline String& operator =(const std::string& s) {
@@ -236,6 +267,30 @@ namespace Rcpp {
236267 buffer_ready = true ;
237268 return *this ;
238269 }
270+ #ifdef RCPP_USING_CXX11
271+ inline String& operator =(String&& other) {
272+ data = other.data ;
273+ token = other.token ;
274+ buffer = std::move (other.buffer );
275+ valid = other.valid ;
276+ buffer_ready = other.buffer_ready ;
277+ enc = other.enc ;
278+ // Erase other.
279+ other.data = R_NilValue;
280+ other.token = R_NilValue;
281+ other.buffer = std::string ();
282+ other.valid = false ;
283+ other.buffer_ready = true ;
284+ other.enc = CE_UTF8;
285+ return *this ;
286+ }
287+ inline String& operator =(std::string&& s) {
288+ buffer = s;
289+ valid = false ;
290+ buffer_ready = true ;
291+ return *this ;
292+ }
293+ #endif
239294 inline String& operator =(const char * s) {
240295 buffer = s;
241296 valid = false ;
0 commit comments