[Rcpp-commits] r3973 - in pkg/Rcpp: . R inst/include/Rcpp/sugar inst/include/Rcpp/sugar/functions inst/include/Rcpp/sugar/tools inst/include/Rcpp/vector man

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Thu Nov 15 14:26:11 CET 2012


Author: romain
Date: 2012-11-15 14:26:11 +0100 (Thu, 15 Nov 2012)
New Revision: 3973

Added:
   pkg/Rcpp/inst/include/Rcpp/sugar/functions/match.h
   pkg/Rcpp/inst/include/Rcpp/sugar/tools/
   pkg/Rcpp/inst/include/Rcpp/sugar/tools/iterator.h
Modified:
   pkg/Rcpp/ChangeLog
   pkg/Rcpp/R/Attributes.R
   pkg/Rcpp/inst/include/Rcpp/sugar/functions/functions.h
   pkg/Rcpp/inst/include/Rcpp/sugar/functions/unique.h
   pkg/Rcpp/inst/include/Rcpp/sugar/sets.h
   pkg/Rcpp/inst/include/Rcpp/sugar/sugar.h
   pkg/Rcpp/inst/include/Rcpp/vector/Vector.h
   pkg/Rcpp/man/evalCpp.Rd
Log:
match

Modified: pkg/Rcpp/ChangeLog
===================================================================
--- pkg/Rcpp/ChangeLog	2012-11-15 12:37:48 UTC (rev 3972)
+++ pkg/Rcpp/ChangeLog	2012-11-15 13:26:11 UTC (rev 3973)
@@ -2,6 +2,13 @@
 
         * include/Rcpp/sugar/logical/SingleLogicalResult.h : apply patch suggested
         by Karl Millar
+        * R/Attributes.R: new R function areMacrosDefined
+        * man/evalCpp.Rd: documentation update
+        * include/Rcpp/sugar/functions/match.h : generic version of match
+        * include/Rcpp/sugar/tools/iterator.h: help iterator that helps writing match 
+        in terms of stl algorithms.
+        * include/Rcpp/vector/Vector.h: class no_init that can be used to create
+        an uninitialized vector. e.g. IntegerVector out = no_init(10) ;
 
 2012-11-14  JJ Allaire <jj at rstudio.org>
 

Modified: pkg/Rcpp/R/Attributes.R
===================================================================
--- pkg/Rcpp/R/Attributes.R	2012-11-15 12:37:48 UTC (rev 3972)
+++ pkg/Rcpp/R/Attributes.R	2012-11-15 13:26:11 UTC (rev 3973)
@@ -221,6 +221,37 @@
     fun()
 }
 
+areMacrosDefined <- function(names, 
+                    depends = character(), 
+                    includes = character(), 
+                    rebuild = FALSE,
+                    showOutput = verbose, 
+                    verbose = getOption( "verbose" ) ){
+ 
+                         
+    code <- sprintf( '
+        LogicalVector get_value(){ 
+            
+            return LogicalVector::create( 
+                %s
+            ) ;
+        }', 
+        
+        paste( sprintf( '    _["%s"] = 
+                #if defined(%s)
+                    true
+                #else
+                    false
+                #endif
+         ', names, names ), collapse = ",\n" )
+    )
+    env <- new.env()
+    cppFunction(code, depends = depends, includes = includes, env = env, 
+                rebuild = rebuild, showOutput = showOutput, verbose = verbose )
+    fun <- env[["get_value"]]
+    fun()
+}
+
 # Scan the source files within a package for attributes and generate code
 # based on the attributes. 
 compileAttributes <- function(pkgdir = ".", verbose = getOption("verbose")) {

Modified: pkg/Rcpp/inst/include/Rcpp/sugar/functions/functions.h
===================================================================
--- pkg/Rcpp/inst/include/Rcpp/sugar/functions/functions.h	2012-11-15 12:37:48 UTC (rev 3972)
+++ pkg/Rcpp/inst/include/Rcpp/sugar/functions/functions.h	2012-11-15 13:26:11 UTC (rev 3973)
@@ -60,5 +60,6 @@
 #include <Rcpp/sugar/functions/which_max.h>
 
 #include <Rcpp/sugar/functions/unique.h>
+#include <Rcpp/sugar/functions/match.h>
 
 #endif

Added: pkg/Rcpp/inst/include/Rcpp/sugar/functions/match.h
===================================================================
--- pkg/Rcpp/inst/include/Rcpp/sugar/functions/match.h	                        (rev 0)
+++ pkg/Rcpp/inst/include/Rcpp/sugar/functions/match.h	2012-11-15 13:26:11 UTC (rev 3973)
@@ -0,0 +1,99 @@
+// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-
+//
+// match.h: Rcpp R/C++ interface class library -- match
+//
+// Copyright (C) 2012   Dirk Eddelbuettel and Romain Francois
+//
+// This file is part of Rcpp.
+//
+// Rcpp is free software: you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// Rcpp is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Rcpp.  If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef Rcpp__sugar__match_h
+#define Rcpp__sugar__match_h
+          
+namespace Rcpp{
+namespace sugar{
+
+template <typename HASH>
+class HashIndexInserter {
+public:
+    HashIndexInserter( HASH& hash_ ) : hash(hash_), index(1){}
+    
+    template <typename T>
+    inline void operator()( T value ){
+        hash.insert( std::make_pair(value, index++) ) ;
+    }
+    
+private:
+    HASH& hash ;
+    int index;
+} ; 
+template <typename HASH>
+class HashIndexFinder {
+public:
+    HashIndexFinder( HASH& hash_) : hash(hash_), end(hash.end()) {}
+    
+    template <typename T>
+    inline int operator()( T value ){
+        typename HASH::const_iterator it = hash.find(value);
+        if( it == end ){
+            return NA_INTEGER ;    
+        } else {
+            return it->second ;    
+        }
+    }
+    
+private:
+    HASH& hash ;
+    typename HASH::const_iterator end ;
+} ;
+
+    
+// version for INTSXP, REALSXP, RAWSXP, CPLXSXP
+template <int RTYPE, typename TABLE_T>        
+class IndexHash {
+public:
+    IndexHash( const TABLE_T& table ): hash() {
+        for_each( get_const_begin(table), get_const_end(table), HashIndexInserter<HASH>(hash) ) ;
+    }
+    
+    template <typename T>
+    IntegerVector match( const T& obj ){
+        int n=obj.size() ;
+        IntegerVector out = no_init(n) ;
+        std::transform( 
+            get_const_begin(obj), get_const_end(obj), 
+            out.begin(), 
+            HashIndexFinder<HASH>(hash)
+        ) ;
+        return out ;
+    }
+ 
+private:
+    typedef RCPP_UNORDERED_MAP< typename Rcpp::traits::storage_type<RTYPE>::type, int > HASH ;
+    typedef typename HASH::const_iterator HASH_iterator ;
+    HASH hash ;    
+}; 
+    
+} // sugar
+
+template <int RTYPE, bool NA, typename T, bool RHS_NA, typename RHS_T>
+inline IntegerVector match( const VectorBase<RTYPE,NA,T>& x, const VectorBase<RTYPE,RHS_NA,RHS_T>& table ){
+    sugar::IndexHash<RTYPE,RHS_T> hash( table.get_ref() ) ;
+    return hash.match( x.get_ref() ) ;
+}
+
+} // Rcpp
+#endif
+

Modified: pkg/Rcpp/inst/include/Rcpp/sugar/functions/unique.h
===================================================================
--- pkg/Rcpp/inst/include/Rcpp/sugar/functions/unique.h	2012-11-15 12:37:48 UTC (rev 3972)
+++ pkg/Rcpp/inst/include/Rcpp/sugar/functions/unique.h	2012-11-15 13:26:11 UTC (rev 3973)
@@ -43,7 +43,7 @@
     
 private:
     
-    RCPP_UNIQUE_SET<STORAGE> set ;
+    RCPP_UNORDERED_SET<STORAGE> set ;
     
 } ;
    
@@ -72,7 +72,7 @@
     
 private:
     
-    RCPP_UNIQUE_SET<std::string> set ;
+    RCPP_UNORDERED_SET<std::string> set ;
    
 } ;
 
@@ -102,7 +102,7 @@
     }
 private:
     
-    RCPP_UNIQUE_SET<SEXP> set ;
+    RCPP_UNORDERED_SET<SEXP> set ;
    
 } ;
 

Modified: pkg/Rcpp/inst/include/Rcpp/sugar/sets.h
===================================================================
--- pkg/Rcpp/inst/include/Rcpp/sugar/sets.h	2012-11-15 12:37:48 UTC (rev 3972)
+++ pkg/Rcpp/inst/include/Rcpp/sugar/sets.h	2012-11-15 13:26:11 UTC (rev 3973)
@@ -23,14 +23,14 @@
 #define Rcpp__sugar__sets_h
 
 #if __cplusplus >= 201103L
-    #define RCPP_UNIQUE_SET std::unordered_set
-    #define RCPP_UNIQUE_MAP std::unordered_map
-#elseif defined(HAS_TR1_UNORDERED_SET)
-    #define RCPP_UNIQUE_SET std::tr1::unordered_set
-    #define RCPP_UNIQUE_MAP std::tr1::unordered_map
+    #define RCPP_UNORDERED_SET std::unordered_set
+    #define RCPP_UNORDERED_MAP std::unordered_map
+#elif defined(HAS_TR1_UNORDERED_SET)
+    #define RCPP_UNORDERED_SET std::tr1::unordered_set
+    #define RCPP_UNORDERED_MAP std::tr1::unordered_map
 #else
-    #define RCPP_UNIQUE_SET std::set
-    #define RCPP_UNIQUE_MAP std::map
+    #define RCPP_UNORDERED_SET std::set
+    #define RCPP_UNORDERED_MAP std::map
 #endif
 
 namespace Rcpp{

Modified: pkg/Rcpp/inst/include/Rcpp/sugar/sugar.h
===================================================================
--- pkg/Rcpp/inst/include/Rcpp/sugar/sugar.h	2012-11-15 12:37:48 UTC (rev 3972)
+++ pkg/Rcpp/inst/include/Rcpp/sugar/sugar.h	2012-11-15 13:26:11 UTC (rev 3973)
@@ -23,6 +23,7 @@
 #define RCPP_SUGAR_H
 
 #include <Rcpp/sugar/sets.h>
+#include <Rcpp/sugar/tools/iterator.h>
 #include <Rcpp/sugar/block/block.h>
 
 #include <Rcpp/sugar/operators/operators.h>

Added: pkg/Rcpp/inst/include/Rcpp/sugar/tools/iterator.h
===================================================================
--- pkg/Rcpp/inst/include/Rcpp/sugar/tools/iterator.h	                        (rev 0)
+++ pkg/Rcpp/inst/include/Rcpp/sugar/tools/iterator.h	2012-11-15 13:26:11 UTC (rev 3973)
@@ -0,0 +1,147 @@
+// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-
+//
+// iterator.h: Rcpp R/C++ interface class library -- 
+//
+// Copyright (C) 2012   Dirk Eddelbuettel and Romain Francois
+//
+// This file is part of Rcpp.
+//
+// Rcpp is free software: you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 2 of the License, or
+// (at your option) any later version.
+//
+// Rcpp is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Rcpp.  If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef Rcpp__sugar__tools_iterator_h
+#define Rcpp__sugar__tools_iterator_h
+
+namespace Rcpp {
+namespace sugar { 
+
+    /* generic sugar iterator type */
+    template <typename T>
+    class SugarIterator {
+    public:
+        
+        typedef int difference_type ;
+        typedef typename Rcpp::traits::storage_type< Rcpp::traits::r_sexptype_traits<T>::rtype >::type STORAGE_TYPE ;
+        typedef STORAGE_TYPE reference ;
+        typedef STORAGE_TYPE* pointer ;
+        typedef std::random_access_iterator_tag iterator_category ;
+        typedef SugarIterator iterator ;
+        
+        SugarIterator( const T& ref_ ) :ref(ref_), index(0) {}
+        SugarIterator( const T& ref_, int index_) : ref(ref_), index(index_) {}
+        SugarIterator( const SugarIterator& other) : ref(other.ref), index(other.index){}
+        
+        inline iterator& operator++(){ index++; return *this ; }
+        inline iterator& operator++(int){ index++; return *this ; }
+        inline iterator& operator--(){ index--; return *this ; }
+        inline iterator& operator--(int){ index--; return *this ; }
+        inline iterator operator+(difference_type n) const {
+			return iterator( ref, index+n ) ;
+		}
+		inline iterator operator-(difference_type n) const {
+			return iterator( ref, index-n ) ;
+		}
+		inline iterator& operator+=(difference_type n) {
+			index += n ;
+			return *this ;
+		}
+		inline iterator& operator-=(difference_type n) {
+			index -= n; 
+			return *this ;
+		}
+        inline reference operator[](int i){
+		    return ref[index+i] ;
+		}
+		
+		inline reference operator*() {
+			return ref[index] ;
+		}
+		inline pointer operator->(){
+			return &ref[index] ;
+		}
+		
+		inline bool operator==( const iterator& y) const {
+			return ( index == y.index ) ;
+		}
+		inline bool operator!=( const iterator& y) const {
+			return ( index != y.index ) ;
+		}
+		inline bool operator<( const iterator& other ) const {
+			return index < other.index ;
+		}
+		inline bool operator>( const iterator& other ) const {
+			return index > other.index ;
+		}
+		inline bool operator<=( const iterator& other ) const {
+			return index <= other.index ;
+		}
+		inline bool operator>=( const iterator& other ) const {
+			return index >= other.index ;
+		}
+		
+		inline difference_type operator-(const iterator& other) const {
+			return index - other.index ;
+		}
+	
+        
+    private:   
+        const T& ref ;
+        int index ;
+    } ;
+    
+    template <typename T> struct sugar_const_iterator_type {
+        typedef SugarIterator<T> type ;
+    } ;
+    template <int RTYPE> struct sugar_const_iterator_type< Rcpp::Vector<RTYPE> >{
+        typedef typename Rcpp::Vector<RTYPE>::const_iterator type ;
+    } ;
+    template <> struct sugar_const_iterator_type< CharacterVector >{
+        typedef SEXP* type ;
+    } ;
+    
+    
+    template <typename T> struct is_sugar_vector : public Rcpp::traits::false_type{} ;
+    template <int RTYPE> struct is_sugar_vector< Rcpp::Vector<RTYPE> > : public Rcpp::traits::true_type{} ;
+    
+    
+    template <typename T>
+    inline typename sugar_const_iterator_type<T>::type get_const_begin__impl(const T& obj, Rcpp::traits::true_type ){
+        return obj.begin() ;
+    }
+    template <typename T>
+    inline typename sugar_const_iterator_type<T>::type get_const_begin__impl(const T& obj, Rcpp::traits::false_type ){
+        typedef typename sugar_const_iterator_type<T>::type const_iterator ; 
+        return const_iterator( obj ) ;
+    }
+    
+    
+    
+    template <typename T>
+    inline typename sugar_const_iterator_type<T>::type get_const_begin(const T& obj){
+        return get_const_begin__impl( obj, typename is_sugar_vector<T>::type() ) ;
+    }
+    /* full specialization for character vectors */
+    template <>
+    inline SEXP* get_const_begin(const CharacterVector& obj){
+        return get_string_ptr(obj) ;
+    }
+    
+    template <typename T>
+    inline typename sugar_const_iterator_type<T>::type get_const_end(const T& obj){
+        return get_const_begin<T>(obj) + obj.size() ;
+    }
+    
+    
+}
+}
+#endif

Modified: pkg/Rcpp/inst/include/Rcpp/vector/Vector.h
===================================================================
--- pkg/Rcpp/inst/include/Rcpp/vector/Vector.h	2012-11-15 12:37:48 UTC (rev 3972)
+++ pkg/Rcpp/inst/include/Rcpp/vector/Vector.h	2012-11-15 13:26:11 UTC (rev 3973)
@@ -22,6 +22,18 @@
 #ifndef Rcpp__vector__Vector_h
 #define Rcpp__vector__Vector_h
 
+class no_init {
+public:
+    no_init(int size_): size(size_){}
+    inline int get() const { return size; }
+    
+    template <int RTYPE>
+    operator Vector<RTYPE>(){ return Rf_allocVector(RTYPE, size) ; }
+    
+private:
+    int size ;
+} ;
+
 template <int RTYPE>
 class Vector :
     public RObject,       
@@ -204,7 +216,7 @@
         RObject::setSEXP( Rf_allocVector( RTYPE, size) ) ;
         fill( u ) ;
     }
-
+    
     Vector( const int& siz, stored_type (*gen)(void) ){
     	RObject::setSEXP( Rf_allocVector( RTYPE, siz) ) ;
         iterator first = begin(), last = end() ;

Modified: pkg/Rcpp/man/evalCpp.Rd
===================================================================
--- pkg/Rcpp/man/evalCpp.Rd	2012-11-15 12:37:48 UTC (rev 3972)
+++ pkg/Rcpp/man/evalCpp.Rd	2012-11-15 13:26:11 UTC (rev 3973)
@@ -1,5 +1,6 @@
 \name{evalCpp}
 \alias{evalCpp}
+\alias{areMacrosDefined}
 \title{
 Evaluate a C++ Expression
 }
@@ -11,11 +12,17 @@
 evalCpp(code, depends = character(), includes = character(), 
         rebuild = FALSE, showOutput = verbose, 
         verbose = getOption("verbose"))
+areMacrosDefined(names, depends = character(), includes = character(), 
+        rebuild = FALSE, showOutput = verbose, 
+        verbose = getOption("verbose"))
 }
 \arguments{
   \item{code}{
 C++ expression to evaluate
 }
+  \item{names}{
+names of the macros we want to test
+}
   \item{depends}{
 see \code{\link{cppFunction}}
 }
@@ -47,5 +54,7 @@
 evalCpp( "__cplusplus" )
 evalCpp( "std::numeric_limits<double>::max()" )
     
+areMacrosDefined( c("__cplusplus", "HAS_TR1" ) )
+
 }
 }



More information about the Rcpp-commits mailing list