Rcpp Version 0.10.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros
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 // proxy.h: Rcpp R/C++ interface class library -- proxies
4 //
5 // Copyright (C) 2010 - 2012 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__proxy_h
23 #define Rcpp__vector__proxy_h
24 
25 namespace internal{
26 
27  template <int RTYPE> class simple_name_proxy {
28  public:
29  typedef ::Rcpp::Vector<RTYPE> VECTOR ;
30  typedef typename ::Rcpp::traits::storage_type<RTYPE>::type CTYPE ;
31  simple_name_proxy( VECTOR& v, const std::string& name_) :
32  parent(v), name(name_){} ;
34  parent(other.parent), name(other.name){} ;
36 
38  set( rhs ) ;
39  return *this ;
40  }
42  set( other.get() ) ;
43  return *this ;
44  }
45 
46  template <typename T>
47  simple_name_proxy& operator=( const T& rhs ){
48  set( caster<T,CTYPE>(rhs) ) ;
49  return *this ;
50  }
51 
52  // TODO: other operators +=, -=, ...
53 
54  operator CTYPE() const {
55  return get() ;
56  }
57 
58  // this helps wrap, for example : wrap( x["foo"] )
59  operator SEXP() const {
60  return ::Rcpp::wrap(get()) ;
61  }
62 
63  private:
65  std::string name;
66  void set( CTYPE rhs ){
67  int index = 0 ;
68  try{
69  index = parent.offset(name) ;
70  parent[ index ] = rhs ;
71  } catch( const index_out_of_bounds& ex ){
72  parent.push_back( rhs, name );
73  }
74  }
75  CTYPE get() const {
76  return parent[ parent.offset(name) ];
77  }
78  } ;
79 
80  template <int RTYPE>
82  public:
83  typedef typename ::Rcpp::Vector<RTYPE> VECTOR ;
84  typedef const char* iterator ;
85  typedef const char& reference ;
86 
87  string_name_proxy( VECTOR& v, const std::string& name_) :
88  parent(v), name(name_){} ;
90  parent(other.parent), name(other.name){} ;
92 
93  string_name_proxy& operator=( const std::string& rhs ){
94  set( rhs ) ;
95  return *this ;
96  }
98  set( other.get() ) ;
99  return *this ;
100  }
101 
102  operator char* (){
103  return get() ;
104  }
105 
106  operator SEXP(){
107  return ::Rf_mkString(get()) ;
108  }
109 
110  inline iterator begin() { return get() ; }
111  inline iterator end(){ return begin() + size() ; }
112  inline reference operator[]( int i ){ return *( get() + i ) ; }
113  inline int size(){ return strlen( get() ) ; }
114 
115  private:
117  std::string name;
118  void set( const std::string& rhs ){
119  int index = 0 ;
120  try{
121  index = parent.offset(name) ;
122  parent[ index ] = rhs ;
123  } catch( const index_out_of_bounds& ex ){
124  parent.push_back( rhs, name );
125  }
126  }
127  char* get(){
128  return parent[ parent.offset(name) ];
129  }
130 
131  } ;
132 
133  template <int RTYPE> class generic_name_proxy {
134  public:
135  typedef ::Rcpp::Vector<RTYPE> VECTOR ;
136  generic_name_proxy( VECTOR& v, const std::string& name_) :
137  parent(v), name(name_){
138  RCPP_DEBUG_2( "generic_name_proxy( VECTOR& = %p, const string& = %s)", v.asSexp(), name_.c_str() );
139  } ;
141  parent(other.parent), name(other.name){} ;
143 
145  set( rhs ) ;
146  return *this ;
147  }
149  set( other.get() ) ;
150  return *this ;
151  }
152 
153  template <typename T>
154  generic_name_proxy& operator=( const T& rhs ){
155  set( ::Rcpp::wrap(rhs) ) ;
156  return *this ;
157  }
158 
159  // TODO: other operators +=, -=, ...
160 
161  operator SEXP() const {
162  return get() ;
163  }
164 
165  template <typename T>
166  operator T() const {
167  #if RCPP_DEBUG_LEVEL > 0
168  SEXP res = get() ;
169  RCPP_DEBUG_1( "generic_name_proxy::get() = <%p> ", res ) ;
170  return ::Rcpp::as<T>( res ) ;
171  #else
172  return ::Rcpp::as<T>( get() ) ;
173  #endif
174  }
175 
176  operator bool() const{
177  return ::Rcpp::as<bool>(get());
178  }
179 
180  private:
182  std::string name;
183  void set( SEXP rhs ){
184  int index = 0 ;
185  try{
186  index = parent.offset(name) ;
187  parent[ index ] = rhs ;
188  } catch( const index_out_of_bounds& ex ){
189  parent.push_back( rhs, name );
190  }
191  }
192  SEXP get() const {
193  return parent[ parent.offset(name) ];
194  }
195  } ;
196 }
197 
198 namespace traits {
199 
200  template <int RTYPE>
202  typedef typename ::Rcpp::internal::simple_name_proxy<RTYPE> type ;
203  } ;
204  template<> struct r_vector_name_proxy<STRSXP>{
205  typedef ::Rcpp::internal::string_name_proxy<STRSXP> type ;
206  } ;
207  template<> struct r_vector_name_proxy<VECSXP>{
208  typedef ::Rcpp::internal::generic_name_proxy<VECSXP> type ;
209  } ;
210  template<> struct r_vector_name_proxy<EXPRSXP>{
211  typedef ::Rcpp::internal::generic_name_proxy<EXPRSXP> type ;
212  } ;
213 
214  template <int RTYPE>
216  typedef typename storage_type<RTYPE>::type& type ;
217  } ;
218  template<> struct r_vector_proxy<STRSXP> {
219  typedef ::Rcpp::internal::string_proxy<STRSXP> type ;
220  } ;
221  template<> struct r_vector_proxy<EXPRSXP> {
222  typedef ::Rcpp::internal::generic_proxy<EXPRSXP> type ;
223  } ;
224  template<> struct r_vector_proxy<VECSXP> {
225  typedef ::Rcpp::internal::generic_proxy<VECSXP> type ;
226  } ;
227 
228  template <int RTYPE>
230  typedef const typename storage_type<RTYPE>::type& type ;
231  } ;
232 
233  template <int RTYPE>
235  typedef typename storage_type<RTYPE>::type* type ;
236  };
237  template <int RTYPE>
239  typedef typename storage_type<RTYPE>::type* type ;
240  };
241 
242  template <int RTYPE> struct proxy_based_iterator{
243  typedef ::Rcpp::internal::Proxy_Iterator< typename r_vector_proxy<RTYPE>::type > type ;
244  } ;
245  template<> struct r_vector_iterator<VECSXP> : proxy_based_iterator<VECSXP>{} ;
246  template<> struct r_vector_iterator<EXPRSXP> : proxy_based_iterator<EXPRSXP>{} ;
247  template<> struct r_vector_iterator<STRSXP> : proxy_based_iterator<STRSXP>{} ;
248 
249 } // traits
250 
251 
252 
253 #endif