Rcpp Version 0.9.10
proxy.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Defines