Rcpp Version 0.9.10
Reference.cpp
Go to the documentation of this file.
00001 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*-
00002 //
00003 // S4.cpp: Rcpp R/C++ interface class library -- S4 objects
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 #include <Rcpp/Reference.h>
00023 #include <Rcpp/exceptions.h>
00024 #include <Rcpp/Vector.h>
00025 
00026 namespace Rcpp {
00027 
00028     Reference::Reference() : S4(){}
00029     
00030     Reference::Reference(SEXP x) : S4(){
00031         set( x) ;
00032     }
00033     
00034     Reference::Reference( const Reference& other) : S4(){
00035         setSEXP( other.asSexp() ) ; 
00036     }
00037     
00038     Reference::Reference( const RObject::SlotProxy& proxy ) : S4() {
00039         set( proxy ) ;
00040     }
00041     Reference::Reference( const RObject::AttributeProxy& proxy ) : S4() {
00042         set( proxy ) ;
00043     }
00044     
00045     Reference& Reference::operator=( const Reference& other){
00046         setSEXP( other.asSexp() ) ;
00047         return *this ;
00048     }
00049     
00050     Reference& Reference::operator=( SEXP other ) {
00051         set( other ) ;
00052         return *this ;
00053     }
00054     
00055     Reference::Reference( const std::string& klass ) : S4(){
00056         // using callback to R as apparently R_do_new_object always makes the same environment
00057         SEXP newSym = Rf_install("new");
00058         SEXP call = PROTECT( Rf_lang2( newSym, Rf_mkString( klass.c_str() ) ) ) ;
00059         setSEXP( Rcpp::internal::try_catch( call ) ) ;
00060         UNPROTECT(1) ; // call
00061     }
00062     
00063     void Reference::set( SEXP x) {
00064         // TODO: check that x is of a reference class
00065         if( ! ::Rf_isS4(x) ){
00066             throw not_reference() ;
00067         } else{
00068             setSEXP( x) ;
00069         }
00070     }
00071     
00072     Reference::FieldProxy::FieldProxy( const Reference& v, const std::string& name) : 
00073         parent(v), field_name(name) {}
00074 
00075     Reference::FieldProxy& Reference::FieldProxy::operator=(const FieldProxy& rhs){
00076         set( rhs.get() ) ;
00077         return *this ;
00078     }
00079     
00080     
00081     SEXP Reference::FieldProxy::get() const {
00082         // TODO: get the field  
00083         
00084         SEXP call = PROTECT( Rf_lang3( 
00085                                                                           R_DollarSymbol, 
00086                                                                           const_cast<Reference&>(parent).asSexp(), 
00087                                                                           Rf_mkString( field_name.c_str() )
00088                                                                            ) ) ;
00089         return Rcpp::internal::try_catch( call ) ;
00090         UNPROTECT(1) ;
00091     }
00092     
00093     void Reference::FieldProxy::set( SEXP x) const {
00094         PROTECT(x);
00095         SEXP dollarGetsSym = Rf_install( "$<-");
00096         SEXP call = PROTECT( Rf_lang4( 
00097                                                                           dollarGetsSym,
00098                                                                           const_cast<Reference&>(parent).asSexp(), 
00099                                                                           Rf_mkString( field_name.c_str() ), 
00100                                                                           x
00101                                                                            ) ) ;
00102         const_cast<Reference&>(parent).setSEXP( Rf_eval( call, R_GlobalEnv ) ); 
00103         UNPROTECT(2) ;
00104     }
00105 
00106     Reference::FieldProxy Reference::field( const std::string& name) const {
00107         return FieldProxy( *this, name );
00108     }
00109     
00110 } // namespace Rcpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Defines