Rcpp Version 1.0.0
String.h
Go to the documentation of this file.
1 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*-
2 //
3 // String.h: Rcpp R/C++ interface class library -- single string
4 //
5 // Copyright (C) 2012 - 2018 Dirk Eddelbuettel and Romain Francois
6 //
7 // This file is part of Rcpp.
8 //
9 // Rcpp is free software: you can redistribute it and/or modify it
10 // under the terms of the GNU General Public License as published by
11 // the Free Software Foundation, either version 2 of the License, or
12 // (at your option) any later version.
13 //
14 // Rcpp is distributed in the hope that it will be useful, but
15 // WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with Rcpp. If not, see <http://www.gnu.org/licenses/>.
21 
22 #ifndef Rcpp__String_h
23 #define Rcpp__String_h
24 
25 #ifndef RCPP_STRING_DEBUG_LEVEL
26 #define RCPP_STRING_DEBUG_LEVEL 0
27 #endif
28 
29 
30 #if RCPP_STRING_DEBUG_LEVEL > 0
31  #define RCPP_STRING_DEBUG_FORMAT "%40s:%4d "
32  #define RCPP_STRING_DEBUG(MSG) Rprintf(RCPP_STRING_DEBUG_FORMAT "%s\n" , short_file_name(__FILE__), __LINE__, MSG);
33  #define RCPP_STRING_DEBUG_1(fmt, MSG) Rprintf(RCPP_STRING_DEBUG_FORMAT fmt "\n" , short_file_name(__FILE__), __LINE__, MSG);
34  #define RCPP_STRING_DEBUG_2(fmt, M1, M2) Rprintf(RCPP_STRING_DEBUG_FORMAT fmt "\n" , short_file_name(__FILE__), __LINE__, M1, M2);
35  #define RCPP_STRING_DEBUG_3(fmt, M1, M2, M3) Rprintf(RCPP_STRING_DEBUG_FORMAT fmt "\n" , short_file_name(__FILE__), __LINE__, M1, M2, M3);
36 #else
37  #define RCPP_STRING_DEBUG(MSG)
38  #define RCPP_STRING_DEBUG_1(fmt, MSG)
39  #define RCPP_STRING_DEBUG_2(fmt, M1, M2)
40  #define RCPP_STRING_DEBUG_3(fmt, M1, M2, M3)
41 #endif
42 
43 namespace Rcpp {
44 
49  class String {
50  public:
53 
55  String(): data(Rf_mkCharCE("", CE_UTF8)), buffer(), valid(true), buffer_ready(true), enc(CE_UTF8) {
57  RCPP_STRING_DEBUG("String()");
58  }
59 
61  String(const String& other) : data(other.get_sexp()), valid(true), buffer_ready(false), enc(Rf_getCharCE(other.get_sexp())) {
63  RCPP_STRING_DEBUG("String(const String&)");
64  }
65 
67  String(SEXP charsxp) : data(R_NilValue) {
68  if (TYPEOF(charsxp) == STRSXP) {
69  data = STRING_ELT(charsxp, 0);
70  } else if (TYPEOF(charsxp) == CHARSXP) {
71  data = charsxp;
72  }
73 
74  if (::Rf_isString(data) && ::Rf_length(data) != 1) {
75  const char* fmt = "Expecting a single string value: "
76  "[type=%s; extent=%i].";
77  throw ::Rcpp::not_compatible(fmt,
78  Rf_type2char(TYPEOF(data)),
79  ::Rf_length(data));
80  }
81 
82  valid = true;
83  buffer_ready = false;
84  enc = Rf_getCharCE(data);
86  RCPP_STRING_DEBUG("String(SEXP)");
87  }
88 
90  String(const StringProxy& proxy): data(proxy.get()), valid(true), buffer_ready(false), enc(Rf_getCharCE(proxy.get())) {
92  RCPP_STRING_DEBUG("String(const StringProxy&)");
93  }
94 
95  String(const StringProxy& proxy, cetype_t enc): data(proxy.get()), valid(true), buffer_ready(false) {
97  set_encoding(enc);
98  RCPP_STRING_DEBUG("String(const StringProxy&, cetype_t)");
99  }
100 
102  String(const const_StringProxy& proxy): data(proxy.get()), valid(true), buffer_ready(false), enc(Rf_getCharCE(proxy.get())) {
104  RCPP_STRING_DEBUG("String(const const_StringProxy&)");
105  }
106 
107  String(const const_StringProxy& proxy, cetype_t enc): data(proxy.get()), valid(true), buffer_ready(false) {
109  set_encoding(enc);
110  RCPP_STRING_DEBUG("String(const const_StringProxy&, cetype_t)");
111  }
112 
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  RCPP_STRING_DEBUG("String(const std::string&, cetype_t)");
117  }
118 
119  String(const std::wstring& s, cetype_t enc = CE_UTF8) : data(internal::make_charsexp(s)), valid(true), buffer_ready(false), enc(enc) {
121  RCPP_STRING_DEBUG("String(const std::wstring&, cetype_t)");
122  }
123 
125  String(const char* s, cetype_t enc = CE_UTF8) : buffer(s), valid(false), buffer_ready(true), enc(enc) {
126  data = R_NilValue;
127  RCPP_STRING_DEBUG("String(const char*, cetype_t)");
128  }
129 
130  String(const wchar_t* s, cetype_t enc = CE_UTF8) : data(internal::make_charsexp(s)), valid(true), buffer_ready(false), enc(enc) {
132  RCPP_STRING_DEBUG("String(const wchar_t* s, cetype_t)");
133  }
134 
136  String(int x) : data(internal::r_coerce<INTSXP,STRSXP>(x)), valid(true), buffer_ready(false), enc(CE_UTF8) {Rcpp_PreserveObject(data);}
137  String(double x) : data(internal::r_coerce<REALSXP,STRSXP>(x)), valid(true), buffer_ready(false), enc(CE_UTF8) {Rcpp_PreserveObject(data);}
138  String(bool x) : data(internal::r_coerce<LGLSXP,STRSXP>(x)), valid(true) , buffer_ready(false), enc(CE_UTF8) {Rcpp_PreserveObject(data);}
139  String(Rcomplex x) : data(internal::r_coerce<CPLXSXP,STRSXP>(x)), valid(true), buffer_ready(false), enc(CE_UTF8) {Rcpp_PreserveObject(data);}
140  String(Rbyte x) : data(internal::r_coerce<RAWSXP,STRSXP>(x)), valid(true), buffer_ready(false), enc(CE_UTF8) {Rcpp_PreserveObject(data);}
141 
144  data = R_NilValue;
145  }
146 
147 
148  inline String& operator=(int x ) { data = Rcpp_ReplaceObject(data, internal::r_coerce<INTSXP ,STRSXP>(x)); valid = true; buffer_ready = false; return *this; }
149  inline String& operator=(double x ) { data = Rcpp_ReplaceObject(data, internal::r_coerce<REALSXP,STRSXP>(x)); valid = true; buffer_ready = false; return *this; }
150  inline String& operator=(Rbyte x ) { data = Rcpp_ReplaceObject(data, internal::r_coerce<RAWSXP ,STRSXP>(x)); valid = true; buffer_ready = false; return *this; }
151  inline String& operator=(bool x ) { data = Rcpp_ReplaceObject(data, internal::r_coerce<LGLSXP ,STRSXP>(x)); valid = true; buffer_ready = false; return *this; }
152  inline String& operator=(Rcomplex x) { data = Rcpp_ReplaceObject(data, internal::r_coerce<CPLXSXP,STRSXP>(x)); valid = true; buffer_ready = false; return *this; }
153  inline String& operator=(SEXP x) { data = Rcpp_ReplaceObject(data, x); valid = true; buffer_ready = false; return *this; }
154  inline String& operator=(const StringProxy& proxy) { data = Rcpp_ReplaceObject(data, proxy.get()); valid = true; buffer_ready=false; return *this; }
155  inline String& operator=(const String& other) { data = Rcpp_ReplaceObject(data, other.get_sexp()); valid = true; buffer_ready = false; return *this; }
156  inline String& operator=(const std::string& s) { buffer = s; valid = false; buffer_ready = true; return *this; }
157  inline String& operator=(const char* s) { buffer = s; valid = false; buffer_ready = true; return *this; }
158 
159  private:
160  template <typename T>
161  inline String& assign_wide_string(const T& s) {
162  data = Rcpp_ReplaceObject(data, internal::make_charsexp(s));
163  valid = true;
164  buffer_ready = false;
165  return *this;
166  }
167 
168  public:
169  inline String& operator=(const std::wstring& s) { return assign_wide_string(s); }
170  inline String& operator=(const wchar_t* s) { return assign_wide_string(s); }
171 
172  inline String& operator+=(const std::string& s) {
173  RCPP_STRING_DEBUG("String::operator+=(std::string)");
174  if (is_na()) return *this;
175  setBuffer(); buffer += s; valid = false;
176  return *this;
177  }
178 
179  inline String& operator+=(const char* s) {
180  RCPP_STRING_DEBUG("String::operator+=(const char*)");
181  if (is_na()) return *this;
182  setBuffer(); buffer += s; valid = false;
183  return *this;
184  }
185  private:
186  template <typename T>
187  inline String& append_wide_string(const T& s) {
188  RCPP_STRING_DEBUG_1("String::operator+=(%s)", DEMANGLE(T));
189  setData();
190  if (is_na()) return *this;
191  const char* buf = CHAR(data);
192  std::wstring tmp(buf, buf + strlen(buf));
193  tmp += s;
194  data = Rcpp_ReplaceObject(data, internal::make_charsexp(tmp));
195  valid = true;
196  buffer_ready = false;
197  return *this;
198  }
199 
200  public:
201 
202  inline String& operator+=(const std::wstring& s) { return append_wide_string(s); }
203  inline String& operator+=(const wchar_t* s) { return append_wide_string(s); }
204 
205  inline String& operator+=(const String& other) {
206  RCPP_STRING_DEBUG("String::operator+=(const char*)");
207  if (is_na()) return *this;
208  if (other.is_na()) { data = Rcpp_ReplaceObject(data, NA_STRING); valid = true; buffer_ready = false; return *this; }
209  setBuffer(); buffer += other; valid = false;
210  return *this;
211  }
212  inline String& operator+=(const StringProxy& proxy) {
213  RCPP_STRING_DEBUG("String::operator+=(const StringProxy&)");
214  if (is_na()) return *this;
215  SEXP proxy_sexp = proxy;
216  if (proxy_sexp == NA_STRING) { data = Rcpp_ReplaceObject(data, NA_STRING); valid = true; buffer_ready = false; return *this;}
217  setBuffer(); buffer += CHAR(proxy_sexp); valid = false;
218  return *this;
219  }
220  inline String& operator+=(const const_StringProxy& proxy) {
221  RCPP_STRING_DEBUG("String::operator+=(const StringProxy&)");
222  if (is_na()) return *this;
223  SEXP proxy_sexp = proxy;
224  if (proxy_sexp == NA_STRING) { data = Rcpp_ReplaceObject(data, NA_STRING); valid = true; buffer_ready = false; return *this;}
225  setBuffer(); buffer += CHAR(proxy_sexp); valid = false;
226  return *this;
227  }
228  inline String& operator+=(SEXP x) {
229  RCPP_STRING_DEBUG("String::operator+=(SEXP)");
230  if (is_na()) return *this;
231  if (x == NA_STRING) { data = Rcpp_ReplaceObject(data, NA_STRING); valid = true; buffer_ready = false; return *this;}
232  setBuffer(); buffer += CHAR(x); valid = false;
233  return *this;
234  }
235  // inline String& operator+=(int x ) { data += char_nocheck(internal::r_coerce<INTSXP ,STRSXP>(x)); return *this; }
236  // inline String& operator+=(double x ) { data += char_nocheck(internal::r_coerce<REALSXP,STRSXP>(x)); return *this; }
237  // inline String& operator+=(Rbyte x ) { data += char_nocheck(internal::r_coerce<RAWSXP ,STRSXP>(x)); return *this; }
238  // inline String& operator+=(bool x ) { data += char_nocheck(internal::r_coerce<LGLSXP ,STRSXP>(x)); return *this; }
239  // inline String& operator+=(Rcomplex x) { data += char_nocheck(internal::r_coerce<CPLXSXP,STRSXP>(x)); return *this; }
240 
241 
242  inline String& replace_first(const char* s, const char* news) {
243  RCPP_STRING_DEBUG_2("String::replace_first(const char* = '%s' , const char* = '%s')", s, news);
244  if (is_na()) return *this;
245  setBuffer();
246  std::string s2 = std::string(s);
247  size_t index = std::distance(buffer.begin(), std::search(buffer.begin(), buffer.end(), s2.begin(), s2.end()));
248  if (index != std::string::npos) buffer.replace(index, strlen(s), news);
249  valid = false;
250  return *this;
251  }
252  inline String& replace_first(const Rcpp::String& s, const char* news) {
253  // replace NA -> do nothing
254  if (s.is_na()) return *this;
255  return replace_first(s.get_cstring(), news);
256  }
257  inline String& replace_first(const char* s, const Rcpp::String& news) {
258  // replace NA -> do nothing
259  if (news.is_na()) return *this;
260  return replace_first(s, news.get_cstring());
261  }
262  inline String& replace_first(const Rcpp::String& s, const Rcpp::String& news) {
263  // replace NA -> do nothing
264  if (s.is_na() || news.is_na()) return *this;
265  return replace_first(s.get_cstring(), news.get_cstring());
266  }
267 
268  inline String& replace_last(const char* s, const char* news) {
269  RCPP_STRING_DEBUG_2("String::replace_last(const char* = '%s' , const char* = '%s')", s, news);
270  if (is_na()) return *this;
271  setBuffer();
272  std::string s2 = std::string(s);
273  size_t index = std::distance(buffer.begin(), std::find_end(buffer.begin(), buffer.end(), s2.begin(), s2.end()));
274  if (index != std::string::npos) buffer.replace(index, strlen(s), news);
275  valid = false;
276  return *this;
277  }
278  inline String& replace_last(const Rcpp::String& s, const char* news) {
279  // replace NA -> do nothing
280  if (s.is_na()) return *this;
281  return replace_last(s.get_cstring(), news);
282  }
283  inline String& replace_last(const char* s, const Rcpp::String& news) {
284  // replace NA -> do nothing
285  if (news.is_na()) return *this;
286  return replace_last(s, news.get_cstring());
287  }
288  inline String& replace_last(const Rcpp::String& s, const Rcpp::String& news) {
289  // replace NA -> do nothing
290  if (s.is_na() || news.is_na()) return *this;
291  return replace_last(s.get_cstring(), news.get_cstring());
292  }
293 
294 
295  inline String& replace_all(const char* s, const char* news) {
296  RCPP_STRING_DEBUG_2("String::replace_all(const char* = '%s' , const char* = '%s')", s, news);
297  if (is_na()) return *this;
298  setBuffer();
299  std::string s2 = std::string(s);
300  std::string::iterator iter = buffer.begin();
301  while(true) {
302  iter = std::search(iter, buffer.end(), s2.begin(), s2.end());
303  if (iter == buffer.end()) break;
304  size_t index = std::distance(buffer.begin(), iter);
305  if (index != std::string::npos) buffer.replace(index, strlen(s), news);
306  }
307  valid = false;
308  return *this;
309  }
310 
311  template <typename LHS, typename RHS>
312  inline String& replace_all(const LHS& s, const RHS& news) {
313  return replace_all(String(s), String(news));
314  }
315 
316  inline String& replace_all(const Rcpp::String& s, const char* news) {
317  // replace NA -> do nothing
318  if (s.is_na()) return *this;
319  return replace_all(s.get_cstring(), news);
320  }
321  inline String& replace_all(const char* s, const Rcpp::String& news) {
322  // replace NA -> do nothing
323  if (news.is_na()) return *this;
324  return replace_all(s, news.get_cstring());
325  }
326  inline String& replace_all(const Rcpp::String& s, const Rcpp::String& news) {
327  // replace NA -> do nothing
328  if (s.is_na() || news.is_na()) return *this;
329  return replace_all(s.get_cstring(), news.get_cstring());
330  }
331 
332  inline String& push_back(const char* s) {
333  if (is_na()) return *this;
334  setBuffer(); valid = false; buffer += s;
335  return *this;
336  }
337  inline String& push_back(const std::string& s) {
338  return push_back(s.c_str());
339  }
340  inline String& push_back(const Rcpp::String& s) {
341  if (is_na()) return *this;
342  if (s.is_na()) { set_na(); return *this; }
343  return push_back(s.get_cstring());
344  }
345 
346  inline String& push_front(const char* s) {
347  if (is_na()) return *this;
348  setBuffer(); valid = false; buffer = s + buffer;
349  return *this;
350  }
351  inline String& push_front(const std::string& s) {
352  return push_front(s.c_str());
353  }
354  inline String& push_front(const Rcpp::String& s) {
355  if (is_na()) return *this;
356  if (s.is_na()) { set_na(); return *this; }
357  return push_front(s.get_cstring());
358  }
359 
360 
361  inline void set_na() {
362  data = Rcpp_ReplaceObject(data, NA_STRING);
363  valid = true; buffer_ready = false;
364  }
365 
366 
367  inline SEXP get_sexp_impl() const {
368 
369  // workaround for h5 package (currently deprecated so updates
370  // to CRAN may not be timely)
371 #ifdef __H5Cpp_H
372  return Rf_mkCharCE(buffer.c_str(), enc);
373 #else
374  if (buffer.find('\0') != std::string::npos)
375  throw embedded_nul_in_string();
376  return Rf_mkCharLenCE(buffer.c_str(), buffer.size(), enc);
377 #endif
378  }
379 
380  inline SEXP get_sexp() const {
381  RCPP_STRING_DEBUG_1("String::get_sexp const (valid = %d) ", valid);
382  return valid ? data : get_sexp_impl();
383  }
384 
385  inline SEXP get_sexp() {
386  RCPP_STRING_DEBUG_1("String::get_sexp (valid = %d) ", valid);
387  setData(); return data;
388  }
389 
390  inline operator std::string() const {
391  return get_cstring();
392  }
393 
394  inline operator std::wstring() const {
395  const char* s = get_cstring();
396  return std::wstring(s, s + strlen(s));
397  }
398 
399  inline const char* get_cstring() const {
400  return buffer_ready ? buffer.c_str() : CHAR(data);
401  }
402 
403  inline cetype_t get_encoding() const {
404  return enc;
405  }
406 
407  inline void set_encoding(cetype_t encoding) {
408  enc = encoding;
409 
410  if (valid) {
411  // TODO: may longjmp on failure to translate?
412  const char* translated = Rf_translateCharUTF8(data);
413  data = Rcpp_ReplaceObject(data, Rf_mkCharCE(translated, encoding));
414  } else {
415  data = get_sexp_impl();
417  valid = true;
418  }
419  }
420 
421  bool operator<(const Rcpp::String& other) const {
422  return strcmp(get_cstring(), other.get_cstring()) < 0;
423  }
424 
425  bool operator==(const Rcpp::String& other) const {
426  return get_sexp() == other.get_sexp();
427  }
428  bool operator!=(const Rcpp::String& other) const {
429  return get_sexp() != other.get_sexp();
430  }
431 
432  bool operator==(const StringProxy& other) const {
433  return get_sexp() == other.get();
434  }
435 
436  bool operator!=(const StringProxy& other) const {
437  return get_sexp() != other.get();
438  }
439 
440  bool operator==(const const_StringProxy& other) const {
441  return get_sexp() == other.get();
442  }
443 
444  bool operator!=(const const_StringProxy& other) const {
445  return get_sexp() != other.get();
446  }
447 
448  bool operator>(const Rcpp::String& other) const {
449  return strcmp(get_cstring(), other.get_cstring()) > 0;
450  }
451 
452  bool operator==(SEXP other) const {
453  return get_sexp() == other;
454  }
455 
456  bool operator!=(SEXP other) const {
457  return get_sexp() != other;
458  }
459 
460  private:
461 
463  SEXP data;
464 
466  std::string buffer;
467 
469  bool valid;
470 
473 
475  cetype_t enc;
476 
477  inline bool is_na() const { return data == NA_STRING; }
478  inline void setBuffer() {
479  if (!buffer_ready) {
480  buffer = char_nocheck(data);
481  buffer_ready = true;
482  }
483  }
484  inline void setData() {
485  RCPP_STRING_DEBUG("setData");
486  if (!valid) {
487  data = get_sexp_impl();
488  Rcpp_PreserveObject(data);
489  valid = true;
490  }
491  }
492  template <typename T> void append(const T& s) { buffer += s;}
493  };
494 
495  namespace traits{
496  template<> struct r_type_traits<Rcpp::String>{ typedef r_type_RcppString_tag r_category; };
497  template<> struct r_sexptype_traits<Rcpp::String>{ enum{ rtype = STRSXP }; };
498  }
499 
500  namespace internal {
501  template <int RTYPE, template <class> class StoragePolicy>
503  set(s.get_sexp());
504  return *this;
505  }
506 
507  template <int RTYPE>
509  RCPP_DEBUG("string_element_converter::get< Rcpp::String >()")
510  return input.get_sexp();
511  }
512 
513  template <>
514  inline SEXP make_charsexp<Rcpp::String>(const Rcpp::String& s) {
515  return s.get_sexp();
516  }
517 
518  template <int RTYPE, template <class> class StoragePolicy>
519  template <typename T>
521  String tmp = get();
522  tmp += rhs;
523  set(tmp);
524  return *this;
525  }
526 
527  }
528 
529 
530  template <>
531  inline SEXP wrap<Rcpp::String>(const Rcpp::String& object) {
532  RCPP_STRING_DEBUG("wrap<String>()");
533  Shield<SEXP> res(Rf_allocVector(STRSXP, 1));
534  SEXP data = object.get_sexp();
535  Rcpp_PreserveObject(data);
536  SET_STRING_ELT(res, 0, data);
537  return res;
538  }
539 
540  inline bool operator==(const String::StringProxy& lhs, const String& rhs) {
541  return rhs == lhs;
542  }
543 
544  inline bool operator!=(const String::StringProxy& lhs, const String& rhs) {
545  return rhs != lhs;
546  }
547 
548  inline bool operator==(const String::const_StringProxy& lhs, const String& rhs) {
549  return rhs == lhs;
550  }
551 
552  inline bool operator!=(const String::const_StringProxy& lhs, const String& rhs) {
553  return rhs != lhs;
554  }
555 
556 } // Rcpp
557 
559 #if defined(RCPP_USING_CXX11) || defined(HAS_TR1)
560 namespace std
561 {
562 #ifndef RCPP_USING_CXX11
563 namespace tr1 {
564 #endif
565  template <>
566  struct hash<Rcpp::String>
567  {
568  size_t operator()(const Rcpp::String & s) const{
569  return hash<string>()(s.get_cstring());
570  }
571  };
572 #ifndef RCPP_USING_CXX11
573 }
574 #endif
575 }
576 #endif
577 
578 #endif
String(const String &other)
Definition: String.h:61
String(Rbyte x)
Definition: String.h:140
String & push_back(const Rcpp::String &s)
Definition: String.h:340
bool operator!=(SEXP other) const
Definition: String.h:456
String(const wchar_t *s, cetype_t enc=CE_UTF8)
Definition: String.h:130
bool buffer_ready
Definition: String.h:472
String(int x)
Definition: String.h:136
#define RCPP_STRING_DEBUG_1(fmt, MSG)
Definition: String.h:38
String & replace_all(const Rcpp::String &s, const char *news)
Definition: String.h:316
String & append_wide_string(const T &s)
Definition: String.h:187
String & operator+=(const const_StringProxy &proxy)
Definition: String.h:220
String & operator+=(const std::string &s)
Definition: String.h:172
const char * char_nocheck(SEXP)
Definition: routines.h:214
String & operator=(const wchar_t *s)
Definition: String.h:170
String(const const_StringProxy &proxy)
Definition: String.h:102
SEXP get_sexp()
Definition: String.h:385
void set_na()
Definition: String.h:361
#define RCPP_DEBUG(MSG)
Definition: debug.h:43
String & replace_all(const char *s, const char *news)
Definition: String.h:295
cetype_t enc
Definition: String.h:475
void set_encoding(cetype_t encoding)
Definition: String.h:407
SEXP Rcpp_ReplaceObject(SEXP x, SEXP y)
Definition: RcppCommon.h:103
String & replace_last(const char *s, const Rcpp::String &news)
Definition: String.h:283
String(double x)
Definition: String.h:137
SEXP get_sexp() const
Definition: String.h:380
#define DEMANGLE(__TYPE__)
Definition: exceptions.h:372
Definition: swap.h:25
String & operator=(double x)
Definition: String.h:149
bool operator>(const Rcpp::String &other) const
Definition: String.h:448
bool operator!=(const Rcpp::String &other) const
Definition: String.h:428
String & replace_first(const char *s, const Rcpp::String &news)
Definition: String.h:257
String & operator+=(const String &other)
Definition: String.h:205
String(const std::string &s, cetype_t enc=CE_UTF8)
Definition: String.h:114
String & replace_first(const Rcpp::String &s, const char *news)
Definition: String.h:252
void setData()
Definition: String.h:484
cetype_t get_encoding() const
Definition: String.h:403
String & operator+=(const wchar_t *s)
Definition: String.h:203
String(const std::wstring &s, cetype_t enc=CE_UTF8)
Definition: String.h:119
bool operator<(const Rcpp::String &other) const
Definition: String.h:421
bool operator!=(const const_StringProxy &other) const
Definition: String.h:444
bool valid
Definition: String.h:469
String(bool x)
Definition: String.h:138
String(const char *s, cetype_t enc=CE_UTF8)
Definition: String.h:125
std::string buffer
Definition: String.h:466
String & operator+=(SEXP x)
Definition: String.h:228
String(const const_StringProxy &proxy, cetype_t enc)
Definition: String.h:107
String & operator+=(const StringProxy &proxy)
Definition: String.h:212
bool operator==(SEXP other) const
Definition: String.h:452
String & operator=(Rcomplex x)
Definition: String.h:152
String(SEXP charsxp)
Definition: String.h:67
String & replace_all(const char *s, const Rcpp::String &news)
Definition: String.h:321
String & operator+=(const char *s)
Definition: String.h:179
String & operator=(const std::wstring &s)
Definition: String.h:169
String & push_back(const char *s)
Definition: String.h:332
#define RCPP_STRING_DEBUG_2(fmt, M1, M2)
Definition: String.h:39
internal::const_string_proxy< STRSXP > const_StringProxy
Definition: String.h:52
SEXP data
Definition: String.h:463
String & replace_last(const char *s, const char *news)
Definition: String.h:268
const char * get_cstring() const
Definition: String.h:399
internal::string_proxy< STRSXP > StringProxy
Definition: String.h:51
String & push_back(const std::string &s)
Definition: String.h:337
void setBuffer()
Definition: String.h:478
String & operator+=(const std::wstring &s)
Definition: String.h:202
bool is_na() const
Definition: String.h:477
String & operator=(const String &other)
Definition: String.h:155
SEXP get(const std::string &name) const
Definition: Environment.h:103
String(const StringProxy &proxy, cetype_t enc)
Definition: String.h:95
String & replace_last(const Rcpp::String &s, const Rcpp::String &news)
Definition: String.h:288
String & operator=(const std::string &s)
Definition: String.h:156
String & push_front(const Rcpp::String &s)
Definition: String.h:354
String & operator=(int x)
Definition: String.h:148
String(Rcomplex x)
Definition: String.h:139
void append(const T &s)
Definition: String.h:492
String & operator=(const char *s)
Definition: String.h:157
String & push_front(const char *s)
Definition: String.h:346
String & operator=(SEXP x)
Definition: String.h:153
bool operator!=(const StringProxy &other) const
Definition: String.h:436
#define RCPP_STRING_DEBUG(MSG)
Definition: String.h:37
String & operator=(const StringProxy &proxy)
Definition: String.h:154
String & push_front(const std::string &s)
Definition: String.h:351
String & operator=(bool x)
Definition: String.h:151
bool operator==(const const_StringProxy &other) const
Definition: String.h:440
Rcpp API.
Definition: algo.h:28
bool operator==(const Rcpp::String &other) const
Definition: String.h:425
String & replace_all(const LHS &s, const RHS &news)
Definition: String.h:312
String & replace_last(const Rcpp::String &s, const char *news)
Definition: String.h:278
String & replace_all(const Rcpp::String &s, const Rcpp::String &news)
Definition: String.h:326
bool operator==(const StringProxy &other) const
Definition: String.h:432
String & operator=(Rbyte x)
Definition: String.h:150
String & replace_first(const Rcpp::String &s, const Rcpp::String &news)
Definition: String.h:262
String & assign_wide_string(const T &s)
Definition: String.h:161
void Rcpp_ReleaseObject(SEXP x)
Definition: RcppCommon.h:97
String(const StringProxy &proxy)
Definition: String.h:90
String & replace_first(const char *s, const char *news)
Definition: String.h:242
SEXP get_sexp_impl() const
Definition: String.h:367
SEXP Rcpp_PreserveObject(SEXP x)
Definition: RcppCommon.h:90