Rcpp Version 0.12.12
string_proxy.h
Go to the documentation of this file.
1 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-
2 //
3 // string_proxy.h: Rcpp R/C++ interface class library --
4 //
5 // Copyright (C) 2010 - 2013 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__vector__string_proxy_h
23 #define Rcpp__vector__string_proxy_h
24 
25 namespace Rcpp{
26 namespace internal{
27 
28  template<int RTYPE> class string_proxy {
29  public:
30 
31  typedef typename ::Rcpp::Vector<RTYPE> VECTOR ;
32  typedef const char* iterator ;
33  typedef const char& reference ;
34 
35  string_proxy() : parent(0), index(-1){};
36 
43  string_proxy( VECTOR& v, R_xlen_t index_ ) : parent(&v), index(index_){}
44 
45  string_proxy( const string_proxy& other ) :
46  parent(other.parent), index(other.index){} ;
47 
56  set( other.get() ) ;
57  return *this ;
58  }
59 
61 
62  string_proxy& operator=( const String& s) ;
63 
70  template <typename T>
71  string_proxy& operator=(const std::basic_string<T>& rhs){
72  set( rhs ) ;
73  return *this ;
74  }
75 
76  string_proxy& operator=(const char* rhs){
77  set( Rf_mkChar( rhs ) ) ;
78  return *this ;
79  }
80 
81  string_proxy& operator=(const wchar_t* rhs){
82  set( internal::make_charsexp( rhs ) ) ;
83  return *this ;
84  }
85 
86 
87  string_proxy& operator=(SEXP rhs){
88  // TODO: check this is a CHARSXP
89  set( rhs ) ;
90  return *this ;
91  }
92 
93  void import( const string_proxy& other){
94  parent = other.parent ;
95  index = other.index ;
96  }
97 
102  template <typename T>
103  string_proxy& operator+=(const T& rhs) ;
104 
109  operator SEXP() const {
110  return get() ;
111  }
112 
118  operator /* const */ char*() const {
119  return const_cast<char*>( CHAR(get()) );
120  }
121 
122  // operator std::wstring() const {
123  // const char* st = CHAR(get()) ;
124  // return std::wstring( st, st+strlen(st) ) ;
125  // }
126 
131  template <int RT>
132  friend std::ostream& operator<<(std::ostream& os, const string_proxy<RT>& proxy);
133 
134  template <int RT>
135  friend std::string operator+( const std::string& x, const string_proxy<RT>& proxy);
136 
137  void swap( string_proxy& other ){
138  Shield<SEXP> tmp( STRING_ELT(*parent, index)) ;
139  SET_STRING_ELT( *parent, index, STRING_ELT( *(other.parent), other.index) ) ;
140  SET_STRING_ELT( *(other.parent), other.index, tmp ) ;
141  }
142 
143  VECTOR* parent;
144  R_xlen_t index ;
145  inline void move( R_xlen_t n ){ index += n ;}
146 
147  inline SEXP get() const {
148  return STRING_ELT( *parent, index ) ;
149  }
150  template <typename T>
151  inline void set( const T& x ){
152  set( internal::make_charsexp(x) ) ;
153  }
154  inline void set(SEXP x){
155  SET_STRING_ELT( *parent, index, x ) ;
156  }
157 
158  inline iterator begin() const { return CHAR( STRING_ELT( *parent, index ) ) ; }
159  inline iterator end() const { return begin() + size() ; }
160  inline R_xlen_t size() const { return strlen( begin() ) ; }
161  inline bool empty() const { return *begin() == '\0' ; }
162  inline reference operator[]( R_xlen_t n ){ return *( begin() + n ) ; }
163 
164  template <typename UnaryOperator>
165  void transform( UnaryOperator op ){
166  buffer = begin() ;
167  std::transform( buffer.begin(), buffer.end(), buffer.begin(), op ) ;
168  set( buffer ) ;
169  }
170 
171  template <typename OutputIterator, typename UnaryOperator>
172  void apply( OutputIterator target, UnaryOperator op){
173  std::transform( begin(), end(), target, op ) ;
174  }
175 
176  template <typename UnaryOperator>
177  void apply( UnaryOperator op){
178  std::for_each( begin(), end(), op );
179  }
180 
181  bool operator==( const char* other){
182  return strcmp( begin(), other ) == 0 ;
183  }
184  bool operator!=( const char* other){
185  return strcmp( begin(), other ) != 0 ;
186  }
187 
188  bool operator==( const string_proxy& other){
189  return strcmp( begin(), other.begin() ) == 0 ;
190  }
191  bool operator!=( const string_proxy& other){
192  return strcmp( begin(), other.begin() ) != 0 ;
193  }
194 
195  bool operator==( SEXP other ) const {
196  return get() == other;
197  }
198 
199  bool operator!=( SEXP other ) const {
200  return get() != other;
201  }
202 
203 
204  private:
205  static std::string buffer ;
206 
207  } ;
208 
209  template <int RT>
210  bool operator<( const string_proxy<RT>& lhs, const string_proxy<RT>& rhs) {
211  return strcmp(
212  const_cast<char *>(lhs.begin() ),
213  const_cast<char *>(rhs.begin())
214  ) < 0 ;
215  }
216 
217  template <int RT>
218  bool operator>( const string_proxy<RT>& lhs, const string_proxy<RT>& rhs) {
219  return strcmp(
220  const_cast<char *>(lhs.begin() ),
221  const_cast<char *>(rhs.begin())
222  ) > 0 ;
223  }
224 
225  template <int RT>
226  bool operator>=( const string_proxy<RT>& lhs, const string_proxy<RT>& rhs) {
227  return strcmp(
228  const_cast<char *>(lhs.begin() ),
229  const_cast<char *>(rhs.begin())
230  ) >= 0 ;
231  }
232 
233  template <int RT>
234  bool operator<=( const string_proxy<RT>& lhs, const string_proxy<RT>& rhs) {
235  return strcmp(
236  const_cast<char *>(lhs.begin() ),
237  const_cast<char *>(rhs.begin())
238  ) <= 0 ;
239  }
240 
241  template<int RTYPE> std::string string_proxy<RTYPE>::buffer ;
242 
243  inline std::ostream& operator<<(std::ostream& os, const string_proxy<STRSXP>& proxy) {
244  os << static_cast<const char*>(proxy) ;
245  return os;
246  }
247 
248  inline std::string operator+( const std::string& x, const string_proxy<STRSXP>& y ){
249  return x + static_cast<const char*>(y) ;
250  }
251 
252 }
253 }
254 
255 #endif
string_proxy(VECTOR &v, R_xlen_t index_)
Definition: string_proxy.h:43
void swap(string_proxy &other)
Definition: string_proxy.h:137
void apply(OutputIterator target, UnaryOperator op)
Definition: string_proxy.h:172
bool operator!=(SEXP other) const
Definition: string_proxy.h:199
string_proxy & operator=(const char *rhs)
Definition: string_proxy.h:76
string_proxy & operator=(const string_proxy &other)
Definition: string_proxy.h:55
string_proxy & operator+=(const T &rhs)
bool operator>=(const const_string_proxy< RT > &lhs, const const_string_proxy< RT > &rhs)
void apply(UnaryOperator op)
Definition: string_proxy.h:177
void transform(UnaryOperator op)
Definition: string_proxy.h:165
string_proxy & operator=(SEXP rhs)
Definition: string_proxy.h:87
bool operator!=(const char *other)
Definition: string_proxy.h:184
friend std::string operator+(const std::string &x, const string_proxy< RT > &proxy)
string_proxy & operator=(const std::basic_string< T > &rhs)
Definition: string_proxy.h:71
bool operator!=(const string_proxy &other)
Definition: string_proxy.h:191
reference operator[](R_xlen_t n)
Definition: string_proxy.h:162
Rcpp API.
Definition: algo.h:28
::Rcpp::Vector< RTYPE > VECTOR
Definition: string_proxy.h:31
static std::string buffer
Definition: string_proxy.h:205
string_proxy(const string_proxy &other)
Definition: string_proxy.h:45
bool operator==(SEXP other) const
Definition: string_proxy.h:195
bool operator==(const char *other)
Definition: string_proxy.h:181
string_proxy & operator=(const wchar_t *rhs)
Definition: string_proxy.h:81
bool operator==(const string_proxy &other)
Definition: string_proxy.h:188
bool operator>(const const_string_proxy< RT > &lhs, const const_string_proxy< RT > &rhs)