|
Rcpp Version 0.9.10
|
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