Rcpp Version 0.9.10
DottedPair.h
Go to the documentation of this file.
00001 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-
00002 //
00003 // DottedPair.h: Rcpp R/C++ interface class library -- dotted pair list template
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_DottedPair_h
00023 #define Rcpp_DottedPair_h
00024 
00025 #include <RcppCommon.h>
00026 #include <Rcpp/exceptions.h>
00027 
00028 #include <Rcpp/Symbol.h>
00029 #include <Rcpp/grow.h>
00030 #include <Rcpp/Named.h>
00031 
00032 #include <Rcpp/RObject.h>
00033 
00034 namespace Rcpp{ 
00035 
00036 class DottedPair : public RObject{
00037 public:
00038 
00039         DottedPair() ;
00040         
00041         DottedPair( const DottedPair& other) : RObject(){
00042                 setSEXP( other.asSexp() ) ;
00043         }
00044         
00045         DottedPair& operator=( const DottedPair& other) ; 
00046         
00047 #ifdef HAS_VARIADIC_TEMPLATES
00048 template<typename... Args> 
00049         DottedPair( const Args&... args) : RObject() {
00050                 setSEXP( pairlist(args...) ) ;
00051         }
00052 #else
00053 
00054 #include <Rcpp/generated/DottedPair__ctors.h> 
00055 
00056 #endif  
00057 
00066         template <typename T>
00067         void push_back( const T& object){
00068                 if( isNULL() ){
00069                         setSEXP( grow( object, m_sexp ) ) ;
00070                 } else {
00071                         SEXP x = m_sexp ;
00072                         /* traverse the pairlist */
00073                         while( !Rf_isNull(CDR(x)) ){
00074                                 x = CDR(x) ;
00075                         }
00076                         SEXP tail = PROTECT( pairlist( object ) ); 
00077                         SETCDR( x, tail ) ;
00078                         UNPROTECT(1) ;
00079                 }
00080         }
00081 
00088         template <typename T>
00089         void push_front( const T& object){
00090                 setSEXP( grow(object, m_sexp) ) ;
00091         }
00092 
00100         template <typename T>
00101         void insert( const size_t& index, const T& object) {
00102                 if( index == 0 ) {
00103                         push_front( object ) ;
00104                 } else{
00105                         if( index <  0 ) throw index_out_of_bounds() ;
00106                         if( isNULL( ) ) throw index_out_of_bounds() ;
00107                         
00108                         if( static_cast<R_len_t>(index) > ::Rf_length(m_sexp) ) throw index_out_of_bounds() ;
00109                         
00110                         size_t i=1;
00111                         SEXP x = m_sexp ;
00112                         while( i < index ){
00113                                 x = CDR(x) ;
00114                                 i++; 
00115                         }
00116                         SEXP tail = PROTECT( grow( object, CDR(x) ) ) ; 
00117                         SETCDR( x, tail ) ;
00118                         UNPROTECT(1) ;
00119                 }
00120         }
00121         
00128         template <typename T>
00129         void replace( const int& index, const T& object ) {
00130                 if( static_cast<R_len_t>(index) >= ::Rf_length(m_sexp) ) throw index_out_of_bounds() ;
00131                 
00132                 /* pretend we do a pairlist so that we get Named to work for us */
00133                 SEXP x = PROTECT(pairlist( object ));
00134                 SEXP y = m_sexp ;
00135                 int i=0;
00136                 while( i<index ){ y = CDR(y) ; i++; }
00137                 
00138                 SETCAR( y, CAR(x) );
00139                 SET_TAG( y, TAG(x) );
00140                 UNPROTECT(1) ;
00141         }
00142 
00143         inline R_len_t length() const { return ::Rf_length(m_sexp) ; }
00144         inline R_len_t size() const { return ::Rf_length(m_sexp) ; }
00145         
00151         void remove( const size_t& index ); 
00152         
00153         class Proxy {
00154         public:
00155                 Proxy( DottedPair& v, const size_t& index_ ); 
00156                 
00157                 /* lvalue uses */
00158                 Proxy& operator=(const Proxy& rhs) ; 
00159                 Proxy& operator=(SEXP rhs) ;
00160                 
00161                 template <typename T>
00162                 Proxy& operator=(const T& rhs){
00163                         SETCAR( node, wrap(rhs) ) ;
00164                         return *this ;
00165                 }
00166                 
00167                 template <typename U>
00168                 Proxy& operator=(const traits::named_object<U>& rhs){
00169                         SETCAR( node, rhs.object ) ;
00170                         SEXP rhsNameSym = ::Rf_install( rhs.name.c_str() ); // cannot be gc()ed once in symbol table
00171                         SET_TAG( node, rhsNameSym ) ;
00172                         return *this ;
00173                 }
00174                 
00175                 template <typename T> operator T() const {
00176                         return as<T>( CAR(node) ) ;
00177                 }
00178                 
00179         private:
00180                 RObject node ;
00181         } ;
00182         
00183         const Proxy operator[]( int i ) const ;
00184         Proxy operator[]( int i )  ;
00185         
00186         friend class Proxy; 
00187         
00188         virtual ~DottedPair() = 0 ;
00189         
00190         template <typename T>
00191         friend DottedPair& operator<<(DottedPair& os, const T& t){
00192                 os.push_back( t ) ;
00193                 return os ;
00194         }
00195         
00196         template <typename T>
00197         friend DottedPair& operator>>( const T& t, DottedPair& s){
00198                 s.push_front(t);
00199                 return s ;
00200         }
00201         
00202 };
00203 
00204 } // namespace Rcpp
00205 
00206 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Defines