@@ -58,8 +58,11 @@ namespace Rcpp {
58
58
}
59
59
60
60
/* * 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
+ }
63
66
RCPP_STRING_DEBUG (" String(const String&)" );
64
67
}
65
68
@@ -111,12 +114,27 @@ namespace Rcpp {
111
114
}
112
115
113
116
/* * 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) {
117
118
RCPP_STRING_DEBUG (" String(const std::string&, cetype_t)" );
118
119
}
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
+ }
119
132
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
120
138
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) {
121
139
token = Rcpp_PreciousPreserve (data);
122
140
RCPP_STRING_DEBUG (" String(const std::wstring&, cetype_t)" );
@@ -220,14 +238,27 @@ namespace Rcpp {
220
238
return *this ;
221
239
}
222
240
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 ;
228
261
}
229
- valid = true ;
230
- buffer_ready = false ;
231
262
return *this ;
232
263
}
233
264
inline String& operator =(const std::string& s) {
@@ -236,6 +267,30 @@ namespace Rcpp {
236
267
buffer_ready = true ;
237
268
return *this ;
238
269
}
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
239
294
inline String& operator =(const char * s) {
240
295
buffer = s;
241
296
valid = false ;
0 commit comments