|
Rcpp Version 0.9.10
|
00001 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*- 00002 // 00003 // proxy.h: Rcpp R/C++ interface class library -- proxies 00004 // 00005 // Copyright (C) 2010 - 2011 Dirk Eddelbuettel and Romain Francois 00006 // 00007 // This file is part of Rcpp. 00008 // 00009 // Rcpp is free software: you can redistribute it and/or modify it 00010 // under the terms of the GNU General Public License as published by 00011 // the Free Software Foundation, either version 2 of the License, or 00012 // (at your option) any later version. 00013 // 00014 // Rcpp is distributed in the hope that it will be useful, but 00015 // WITHOUT ANY WARRANTY; without even the implied warranty of 00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 // GNU General Public License for more details. 00018 // 00019 // You should have received a copy of the GNU General Public License 00020 // along with Rcpp. If not, see <http://www.gnu.org/licenses/>. 00021 00022 #ifndef Rcpp__vector__proxy_h 00023 #define Rcpp__vector__proxy_h 00024 00025 namespace internal{ 00026 00027 template <int RTYPE> class simple_name_proxy { 00028 public: 00029 typedef ::Rcpp::Vector<RTYPE> VECTOR ; 00030 typedef typename ::Rcpp::traits::storage_type<RTYPE>::type CTYPE ; 00031 simple_name_proxy( VECTOR& v, const std::string& name_) : 00032 parent(v), name(name_){} ; 00033 simple_name_proxy( const simple_name_proxy& other ) : 00034 parent(other.parent), name(other.name){} ; 00035 ~simple_name_proxy() {} ; 00036 00037 simple_name_proxy& operator=( CTYPE rhs ){ 00038 set( rhs ) ; 00039 return *this ; 00040 } 00041 simple_name_proxy& operator=( const simple_name_proxy& other){ 00042 set( other.get() ) ; 00043 return *this ; 00044 } 00045 00046 template <typename T> 00047 simple_name_proxy& operator=( const T& rhs ){ 00048 set( caster<T,CTYPE>(rhs) ) ; 00049 return *this ; 00050 } 00051 00052 // TODO: other operators +=, -=, ... 00053 00054 operator CTYPE() const { 00055 return get() ; 00056 } 00057 00058 // this helps wrap, for example : wrap( x["foo"] ) 00059 operator SEXP() const { 00060 return ::Rcpp::wrap(get()) ; 00061 } 00062 00063 private: 00064 VECTOR& parent ; 00065 std::string name; 00066 void set( CTYPE rhs ){ 00067 int index = 0 ; 00068 try{ 00069 index = parent.offset(name) ; 00070 parent[ index ] = rhs ; 00071 } catch( const index_out_of_bounds& ex ){ 00072 parent.push_back( rhs, name ); 00073 } 00074 } 00075 CTYPE get() const { 00076 return parent[ parent.offset(name) ]; 00077 } 00078 } ; 00079 00080 template <int RTYPE> 00081 class string_name_proxy{ 00082 public: 00083 typedef typename ::Rcpp::Vector<RTYPE> VECTOR ; 00084 typedef const char* iterator ; 00085 typedef const char& reference ; 00086 00087 string_name_proxy( VECTOR& v, const std::string& name_) : 00088 parent(v), name(name_){} ; 00089 string_name_proxy( const string_name_proxy& other ) : 00090 parent(other.parent), name(other.name){} ; 00091 ~string_name_proxy(){} ; 00092 00093 string_name_proxy& operator=( const std::string& rhs ){ 00094 set( rhs ) ; 00095 return *this ; 00096 } 00097 string_name_proxy& operator=( const string_name_proxy& other){ 00098 set( other.get() ) ; 00099 return *this ; 00100 } 00101 00102 operator char* (){ 00103 return get() ; 00104 } 00105 00106 operator SEXP(){ 00107 return ::Rf_mkString(get()) ; 00108 } 00109 00110 inline iterator begin() { return get() ; } 00111 inline iterator end(){ return begin() + size() ; } 00112 inline reference operator[]( int i ){ return *( get() + i ) ; } 00113 inline int size(){ return strlen( get() ) ; } 00114 00115 private: 00116 VECTOR& parent ; 00117 std::string name; 00118 void set( const std::string& rhs ){ 00119 int index = 0 ; 00120 try{ 00121 index = parent.offset(name) ; 00122 parent[ index ] = rhs ; 00123 } catch( const index_out_of_bounds& ex ){ 00124 parent.push_back( rhs, name ); 00125 } 00126 } 00127 char* get(){ 00128 return parent[ parent.offset(name) ]; 00129 } 00130 00131 } ; 00132 00133 template <int RTYPE> class generic_name_proxy { 00134 public: 00135 typedef ::Rcpp::Vector<RTYPE> VECTOR ; 00136 generic_name_proxy( VECTOR& v, const std::string& name_) : 00137 parent(v), name(name_){ 00138 RCPP_DEBUG_2( "generic_name_proxy( VECTOR& = %p, const string& = %s)", v.asSexp(), name_.c_str() ); 00139 } ; 00140 generic_name_proxy( const generic_name_proxy& other ) : 00141 parent(other.parent), name(other.name){} ; 00142 ~generic_name_proxy(){} ; 00143 00144 generic_name_proxy& operator=( SEXP rhs ){ 00145 set( rhs ) ; 00146 return *this ; 00147 } 00148 generic_name_proxy& operator=( const generic_name_proxy& other){ 00149 set( other.get() ) ; 00150 return *this ; 00151 } 00152 00153 template <typename T> 00154 generic_name_proxy& operator=( const T& rhs ){ 00155 set( ::Rcpp::wrap(rhs) ) ; 00156 return *this ; 00157 } 00158 00159 // TODO: other operators +=, -=, ... 00160 00161 operator SEXP() const { 00162 return get() ; 00163 } 00164 00165 template <typename T> 00166 operator T() const { 00167 #if RCPP_DEBUG_LEVEL > 0 00168 SEXP res = get() ; 00169 RCPP_DEBUG_1( "generic_name_proxy::get() = <%p> ", res ) ; 00170 return ::Rcpp::as<T>( res ) ; 00171 #else 00172 return ::Rcpp::as<T>( get() ) ; 00173 #endif 00174 } 00175 00176 operator bool() const{ 00177 return ::Rcpp::as<bool>(get()); 00178 } 00179 00180 private: 00181 VECTOR& parent ; 00182 std::string name; 00183 void set( SEXP rhs ){ 00184 int index = 0 ; 00185 try{ 00186 index = parent.offset(name) ; 00187 parent[ index ] = rhs ; 00188 } catch( const index_out_of_bounds& ex ){ 00189 parent.push_back( rhs, name ); 00190 } 00191 } 00192 SEXP get() const { 00193 return parent[ parent.offset(name) ]; 00194 } 00195 } ; 00196 } 00197 00198 namespace traits { 00199 00200 template <int RTYPE> 00201 struct r_vector_name_proxy{ 00202 typedef typename ::Rcpp::internal::simple_name_proxy<RTYPE> type ; 00203 } ; 00204 template<> struct r_vector_name_proxy<STRSXP>{ 00205 typedef ::Rcpp::internal::string_name_proxy<STRSXP> type ; 00206 } ; 00207 template<> struct r_vector_name_proxy<VECSXP>{ 00208 typedef ::Rcpp::internal::generic_name_proxy<VECSXP> type ; 00209 } ; 00210 template<> struct r_vector_name_proxy<EXPRSXP>{ 00211 typedef ::Rcpp::internal::generic_name_proxy<EXPRSXP> type ; 00212 } ; 00213 00214 template <int RTYPE> 00215 struct r_vector_proxy{ 00216 typedef typename storage_type<RTYPE>::type& type ; 00217 } ; 00218 template<> struct r_vector_proxy<STRSXP> { 00219 typedef ::Rcpp::internal::string_proxy<STRSXP> type ; 00220 } ; 00221 template<> struct r_vector_proxy<EXPRSXP> { 00222 typedef ::Rcpp::internal::generic_proxy<EXPRSXP> type ; 00223 } ; 00224 template<> struct r_vector_proxy<VECSXP> { 00225 typedef ::Rcpp::internal::generic_proxy<VECSXP> type ; 00226 } ; 00227 00228 template <int RTYPE> 00229 struct r_vector_iterator { 00230 typedef typename storage_type<RTYPE>::type* type ; 00231 }; 00232 template <int RTYPE> struct proxy_based_iterator{ 00233 typedef ::Rcpp::internal::Proxy_Iterator< typename r_vector_proxy<RTYPE>::type > type ; 00234 } ; 00235 template<> struct r_vector_iterator<VECSXP> : proxy_based_iterator<VECSXP>{} ; 00236 template<> struct r_vector_iterator<EXPRSXP> : proxy_based_iterator<EXPRSXP>{} ; 00237 template<> struct r_vector_iterator<STRSXP> : proxy_based_iterator<STRSXP>{} ; 00238 00239 } // traits 00240 00241 00242 00243 #endif