Rcpp Version 0.9.10
RangeIndexer.h
Go to the documentation of this file.
00001 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-
00002 //
00003 // RangeIndexer.h: Rcpp R/C++ interface class library --
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__RangeIndexer_h
00023 #define Rcpp__vector__RangeIndexer_h
00024        
00025 #define UNROLL_LOOP(OP)                              \
00026     typedef typename ::Rcpp::traits::Extractor<RTYPE,NA,T>::type EXT ; \
00027     const EXT& input( x.get_ref() ) ;                   \
00028     int __trip_count = (size_) >> 2;                 \
00029     int i=0 ;                                        \
00030     for ( ; __trip_count > 0 ; --__trip_count) {     \
00031         start[i] OP input[i] ; i++ ;                 \
00032         start[i] OP input[i] ; i++ ;                 \
00033         start[i] OP input[i] ; i++ ;                 \
00034         start[i] OP input[i] ; i++ ;                 \
00035     }                                                \
00036     switch (size_ - i){                              \
00037       case 3:                                        \
00038           start[i] OP input[i] ; i++ ;               \
00039       case 2:                                        \
00040           start[i] OP input[i] ; i++ ;               \
00041       case 1:                                        \
00042           start[i] OP input[i] ; i++ ;               \
00043       case 0:                                        \
00044       default:                                       \
00045           return *this ;                             \
00046     }
00047 
00048 
00049 
00050 namespace internal{
00051 
00052 template <int RTYPE, typename VECTOR>
00053 class RangeIndexer {
00054 public:
00055         typedef typename VECTOR::Proxy Proxy ;
00056         typedef typename VECTOR::iterator iterator ;
00057         
00058         // TODO: check if the indexer is valid
00059         RangeIndexer( VECTOR& vec_, const Rcpp::Range& range_) : 
00060                 start(vec_.begin() + range_.get_start() ), size_( range_.size() ) {}
00061         
00062                 // TODO: size exceptions
00063         template <bool NA, typename T>  
00064         RangeIndexer& operator=( const Rcpp::VectorBase<RTYPE,NA,T>& x){
00065             UNROLL_LOOP(=)
00066         }
00067         
00068         template <bool NA, typename T>  
00069         RangeIndexer& operator+=( const Rcpp::VectorBase<RTYPE,NA,T>& x){
00070                  UNROLL_LOOP(+=)
00071         }
00072         
00073         template <bool NA, typename T>  
00074         RangeIndexer& operator*=( const Rcpp::VectorBase<RTYPE,NA,T>& x){
00075                 UNROLL_LOOP(*=)
00076         }
00077         
00078         template <bool NA, typename T>  
00079         RangeIndexer& operator-=( const Rcpp::VectorBase<RTYPE,NA,T>& x){
00080                 UNROLL_LOOP(-=)
00081         }
00082         
00083         template <bool NA, typename T>  
00084         RangeIndexer& operator/=( const Rcpp::VectorBase<RTYPE,NA,T>& x){
00085                 UNROLL_LOOP(/=)
00086         }
00087         
00088         inline Proxy operator[]( int i ){
00089             return start[i] ;
00090         }
00091         
00092         inline int size(){
00093                 return size_ ;
00094         }
00095         
00096 private:
00097         iterator start ;
00098         int size_ ;
00099 } ;
00100         
00101 }
00102 
00103 #undef UNROLL_LOOP
00104 
00105 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Defines