Rcpp Version 1.0.0
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 - 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__vector__proxy_h
23 #define Rcpp__vector__proxy_h
24 
25 namespace Rcpp{
26 namespace internal{
27 
28  template <int RTYPE, template <class> class StoragePolicy>
29  class simple_name_proxy {
30  public:
31  typedef ::Rcpp::Vector<RTYPE, StoragePolicy> VECTOR ;
32  typedef typename ::Rcpp::traits::storage_type<RTYPE>::type CTYPE ;
33 
34  simple_name_proxy( VECTOR& v, const std::string& name_) :
35  parent(v), name(name_){} ;
37  parent(other.parent), name(other.name){} ;
39 
41  set( rhs ) ;
42  return *this ;
43  }
45  set( other.get() ) ;
46  return *this ;
47  }
48 
49  template <typename T>
50  simple_name_proxy& operator=( const T& rhs ){
51  set( caster<T,CTYPE>(rhs) ) ;
52  return *this ;
53  }
54 
55  // TODO: other operators +=, -=, ...
56 
57  operator CTYPE() const {
58  return get() ;
59  }
60 
61  // this helps wrap, for example : wrap( x["foo"] )
62  operator SEXP() const {
63  return ::Rcpp::wrap(get()) ;
64  }
65 
66  private:
67  VECTOR& parent ;
68  std::string name;
69  void set( CTYPE rhs ){
70  R_xlen_t index = 0 ;
71  try{
72  index = parent.offset(name) ;
73  parent[ index ] = rhs ;
74  } catch( const index_out_of_bounds& ex ){
75  parent.push_back( rhs, name );
76  }
77  }
78  CTYPE get() const {
79  return parent[ parent.offset(name) ];
80  }
81  } ;
82 
83  template <int RTYPE, template <class> class StoragePolicy>
84  class string_name_proxy{
85  public:
86  typedef typename ::Rcpp::Vector<RTYPE, StoragePolicy> VECTOR ;
87  typedef const char* iterator ;
88  typedef const char& reference ;
89 
90  string_name_proxy( VECTOR& v, const std::string& name_) :
91  parent(v), name(name_){} ;
93  parent(other.parent), name(other.name){} ;
95 
96  string_name_proxy& operator=( const std::string& rhs ){
97  set( rhs ) ;
98  return *this ;
99  }
101  set( other.get() ) ;
102  return *this ;
103  }
104 
105  operator char* () const {
106  return get() ;
107  }
108 
109  operator SEXP() const {
110  return ::Rf_mkString(get()) ;
111  }
112 
113  inline iterator begin() { return get() ; }
114  inline iterator end(){ return begin() + size() ; }
115  inline reference operator[]( R_xlen_t i ){ return *( get() + i ) ; }
116  inline R_xlen_t size(){ return strlen( get() ) ; }
117 
118  private:
119  VECTOR& parent ;
120  std::string name;
121  void set( const std::string& rhs ){
122  R_xlen_t index = 0 ;
123  try{
124  index = parent.offset(name) ;
125  parent[ index ] = rhs ;
126  } catch( const index_out_of_bounds& ex ){
127  parent.push_back( rhs, name );
128  }
129  }
130  char* get() const {
131  return parent[ parent.offset(name) ];
132  }
133 
134  } ;
135 
136  template <int RTYPE, template <class> class StoragePolicy>
137  class generic_name_proxy {
138  public:
139  typedef ::Rcpp::Vector<RTYPE, StoragePolicy> VECTOR ;
140  generic_name_proxy( VECTOR& v, const std::string& name_) :
141  parent(v), name(name_){}
143  parent(other.parent), name(other.name){}
145 
147  set( rhs ) ;
148  return *this ;
149  }
151  set( other.get() ) ;
152  return *this ;
153  }
154 
155  template <typename T>
156  generic_name_proxy& operator=( const T& rhs ){
157  set(Shield<SEXP>(wrap(rhs)));
158  return *this ;
159  }
160 
161  // TODO: other operators +=, -=, ...
162 
163  operator SEXP() const {
164  return get() ;
165  }
166 
167  template <typename T>
168  operator T() const {
169  #if RCPP_DEBUG_LEVEL > 0
170  SEXP res = get() ;
171  RCPP_DEBUG_1( "generic_name_proxy::get() = <%p> ", res ) ;
172  return ::Rcpp::as<T>( res ) ;
173  #else
174  return ::Rcpp::as<T>( get() ) ;
175  #endif
176  }
177 
178  private:
179  VECTOR& parent ;
180  std::string name;
181  void set( SEXP rhs ){
182  R_xlen_t index = 0 ;
183  try{
184  index = parent.offset(name) ;
185  parent[ index ] = rhs ;
186  } catch( const index_out_of_bounds& ex ){
187  parent.push_back( rhs, name );
188  }
189  }
190  SEXP get() const {
191  return parent[ parent.offset(name) ];
192  }
193  } ;
194 }
195 
196 namespace traits {
197 
198  template <int RTYPE, template <class> class StoragePolicy>
199  struct r_vector_name_proxy{
200  typedef typename ::Rcpp::internal::simple_name_proxy<RTYPE, StoragePolicy> type ;
201  } ;
202  template<template <class> class StoragePolicy>
203  struct r_vector_name_proxy<STRSXP, StoragePolicy>{
204  typedef ::Rcpp::internal::string_name_proxy<STRSXP, StoragePolicy> type ;
205  } ;
206  template<template <class> class StoragePolicy>
207  struct r_vector_name_proxy<VECSXP, StoragePolicy>{
208  typedef ::Rcpp::internal::generic_name_proxy<VECSXP, StoragePolicy> type ;
209  } ;
210  template<template <class> class StoragePolicy>
211  struct r_vector_name_proxy<EXPRSXP, StoragePolicy>{
212  typedef ::Rcpp::internal::generic_name_proxy<EXPRSXP, StoragePolicy> type ;
213  } ;
214 
215  template <int RTYPE, template <class> class StoragePolicy>
216  struct r_vector_proxy{
217  typedef typename storage_type<RTYPE>::type& type ;
218  } ;
219  template<template <class> class StoragePolicy>
220  struct r_vector_proxy<STRSXP, StoragePolicy> {
221  typedef ::Rcpp::internal::string_proxy<STRSXP, StoragePolicy> type ;
222  } ;
223  template<template <class> class StoragePolicy>
224  struct r_vector_proxy<EXPRSXP, StoragePolicy> {
225  typedef ::Rcpp::internal::generic_proxy<EXPRSXP, StoragePolicy> type ;
226  } ;
227  template<template <class> class StoragePolicy>
228  struct r_vector_proxy<VECSXP, StoragePolicy> {
229  typedef ::Rcpp::internal::generic_proxy<VECSXP, StoragePolicy> type ;
230  } ;
231 
232  template <int RTYPE, template <class> class StoragePolicy>
233  struct r_vector_const_proxy{
234  typedef const typename storage_type<RTYPE>::type& type ;
235  } ;
236  template<template <class> class StoragePolicy>
237  struct r_vector_const_proxy<STRSXP, StoragePolicy> {
238  typedef ::Rcpp::internal::const_string_proxy<STRSXP, StoragePolicy> type ;
239  } ;
240  template<template <class> class StoragePolicy>
241  struct r_vector_const_proxy<VECSXP, StoragePolicy> {
242  typedef ::Rcpp::internal::const_generic_proxy<VECSXP, StoragePolicy> type ;
243  } ;
244  template<template <class> class StoragePolicy>
245  struct r_vector_const_proxy<EXPRSXP, StoragePolicy> {
246  typedef ::Rcpp::internal::const_generic_proxy<EXPRSXP, StoragePolicy> type ;
247  } ;
248 
249  template <int RTYPE, template <class> class StoragePolicy>
250  struct r_vector_iterator {
251  typedef typename storage_type<RTYPE>::type* type ;
252  };
253  template <int RTYPE, template <class> class StoragePolicy>
254  struct r_vector_const_iterator {
255  typedef const typename storage_type<RTYPE>::type* type ;
256  };
257 
258  template <int RTYPE, template <class> class StoragePolicy>
260  typedef ::Rcpp::internal::Proxy_Iterator< typename r_vector_proxy<RTYPE, StoragePolicy>::type > type ;
261  } ;
262  template<template <class> class StoragePolicy> struct r_vector_iterator<VECSXP, StoragePolicy> : proxy_based_iterator<VECSXP, StoragePolicy>{} ;
263  template<template <class> class StoragePolicy> struct r_vector_iterator<EXPRSXP, StoragePolicy> : proxy_based_iterator<EXPRSXP, StoragePolicy>{} ;
264  template<template <class> class StoragePolicy> struct r_vector_iterator<STRSXP, StoragePolicy> : proxy_based_iterator<STRSXP, StoragePolicy>{} ;
265 
266  template <int RTYPE, template <class> class StoragePolicy>
268  typedef ::Rcpp::internal::Proxy_Iterator< typename r_vector_const_proxy<RTYPE, StoragePolicy>::type > type ;
269  } ;
270  template<template <class> class StoragePolicy> struct r_vector_const_iterator<VECSXP, StoragePolicy> : proxy_based_const_iterator<VECSXP, StoragePolicy>{} ;
271  template<template <class> class StoragePolicy> struct r_vector_const_iterator<EXPRSXP, StoragePolicy> : proxy_based_const_iterator<EXPRSXP, StoragePolicy>{} ;
272  template<template <class> class StoragePolicy> struct r_vector_const_iterator<STRSXP, StoragePolicy> : proxy_based_const_iterator<STRSXP, StoragePolicy>{} ;
273 
274 } // traits
275 }
276 
277 #endif
generic_name_proxy(VECTOR &v, const std::string &name_)
Definition: proxy.h:140
::Rcpp::internal::generic_proxy< EXPRSXP, StoragePolicy > type
Definition: proxy.h:225
string_name_proxy(const string_name_proxy &other)
Definition: proxy.h:92
::Rcpp::internal::simple_name_proxy< RTYPE, StoragePolicy > type
Definition: proxy.h:200
simple_name_proxy(VECTOR &v, const std::string &name_)
Definition: proxy.h:34
string_name_proxy & operator=(const string_name_proxy &other)
Definition: proxy.h:100
::Rcpp::internal::string_proxy< STRSXP, StoragePolicy > type
Definition: proxy.h:221
string_name_proxy(VECTOR &v, const std::string &name_)
Definition: proxy.h:90
::Rcpp::internal::Proxy_Iterator< typename r_vector_const_proxy< RTYPE, StoragePolicy >::type > type
Definition: proxy.h:268
::Rcpp::internal::Proxy_Iterator< typename r_vector_proxy< RTYPE, StoragePolicy >::type > type
Definition: proxy.h:260
const storage_type< RTYPE >::type & type
Definition: proxy.h:234
generic_name_proxy(const generic_name_proxy &other)
Definition: proxy.h:142
::Rcpp::internal::generic_name_proxy< EXPRSXP, StoragePolicy > type
Definition: proxy.h:212
::Rcpp::Vector< RTYPE, StoragePolicy > VECTOR
Definition: proxy.h:139
generic_name_proxy & operator=(SEXP rhs)
Definition: proxy.h:146
::Rcpp::internal::generic_proxy< VECSXP, StoragePolicy > type
Definition: proxy.h:229
#define RCPP_DEBUG_1(fmt, MSG)
Definition: debug.h:44
simple_name_proxy(const simple_name_proxy &other)
Definition: proxy.h:36
R_xlen_t offset(const int &i, const int &j) const
Definition: Vector.h:281
simple_name_proxy & operator=(const T &rhs)
Definition: proxy.h:50
generic_name_proxy & operator=(const T &rhs)
Definition: proxy.h:156
::Rcpp::internal::const_generic_proxy< EXPRSXP, StoragePolicy > type
Definition: proxy.h:246
::Rcpp::Vector< RTYPE, StoragePolicy > VECTOR
Definition: proxy.h:86
::Rcpp::Vector< RTYPE, StoragePolicy > VECTOR
Definition: proxy.h:31
void push_back(const T &object)
Definition: Vector.h:450
::Rcpp::internal::generic_name_proxy< VECSXP, StoragePolicy > type
Definition: proxy.h:208
simple_name_proxy & operator=(CTYPE rhs)
Definition: proxy.h:40
::Rcpp::traits::storage_type< RTYPE >::type CTYPE
Definition: proxy.h:32
generic_name_proxy & operator=(const generic_name_proxy &other)
Definition: proxy.h:150
storage_type< RTYPE >::type & type
Definition: proxy.h:217
::Rcpp::internal::string_name_proxy< STRSXP, StoragePolicy > type
Definition: proxy.h:204
SEXP wrap(const Date &date)
Definition: Date.h:38
storage_type< RTYPE >::type * type
Definition: proxy.h:251
::Rcpp::internal::const_string_proxy< STRSXP, StoragePolicy > type
Definition: proxy.h:238
string_name_proxy & operator=(const std::string &rhs)
Definition: proxy.h:96
Rcpp API.
Definition: algo.h:28
const storage_type< RTYPE >::type * type
Definition: proxy.h:255
simple_name_proxy & operator=(const simple_name_proxy &other)
Definition: proxy.h:44
reference operator[](R_xlen_t i)
Definition: proxy.h:115
::Rcpp::internal::const_generic_proxy< VECSXP, StoragePolicy > type
Definition: proxy.h:242