[Rcpp-commits] r1782 - in pkg/Rcpp/inst: . include include/Rcpp/internal include/Rcpp/sugar/matrix include/Rcpp/traits include/Rcpp/vector unitTests

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Mon Jul 5 15:17:43 CEST 2010


Author: romain
Date: 2010-07-05 15:17:42 +0200 (Mon, 05 Jul 2010)
New Revision: 1782

Added:
   pkg/Rcpp/inst/include/Rcpp/traits/matrix_interface.h
Modified:
   pkg/Rcpp/inst/ChangeLog
   pkg/Rcpp/inst/include/Rcpp/internal/wrap.h
   pkg/Rcpp/inst/include/Rcpp/internal/wrap_forward.h
   pkg/Rcpp/inst/include/Rcpp/sugar/matrix/col.h
   pkg/Rcpp/inst/include/Rcpp/sugar/matrix/row.h
   pkg/Rcpp/inst/include/Rcpp/vector/MatrixBase.h
   pkg/Rcpp/inst/include/RcppCommon.h
   pkg/Rcpp/inst/unitTests/runit.sugar.matrix.R
Log:
one more sfinae trick to detect matrix interface

Modified: pkg/Rcpp/inst/ChangeLog
===================================================================
--- pkg/Rcpp/inst/ChangeLog	2010-07-05 11:45:11 UTC (rev 1781)
+++ pkg/Rcpp/inst/ChangeLog	2010-07-05 13:17:42 UTC (rev 1782)
@@ -4,6 +4,9 @@
 	
 	* inst/include/Rcpp/vector/Matrix.h: move ncol, nrow, rows and cols in 
 	Matrix (used to be in Vector)
+	
+	* inst/include/Rcpp/traits/matrix_interface.h: new SFINAE helper to detect
+	matrix interface (helps matrix sugar expressions)
 
 2010-07-02  Romain Francois <romain at r-enthusiasts.com>
 

Modified: pkg/Rcpp/inst/include/Rcpp/internal/wrap.h
===================================================================
--- pkg/Rcpp/inst/include/Rcpp/internal/wrap.h	2010-07-05 11:45:11 UTC (rev 1781)
+++ pkg/Rcpp/inst/include/Rcpp/internal/wrap.h	2010-07-05 13:17:42 UTC (rev 1782)
@@ -31,8 +31,9 @@
 namespace Rcpp{
 
 template <typename T> SEXP wrap( const T& object ) ;
+
+namespace internal{
 	
-namespace internal{
 	template <typename InputIterator> SEXP range_wrap(InputIterator first, InputIterator last) ;
 	template <typename InputIterator> SEXP rowmajor_wrap(InputIterator first, int nrow, int ncol) ;
 
@@ -407,6 +408,28 @@
 }
 
 
+template <typename T>
+SEXP wrap_dispatch_unknown_iterable__matrix_interface( const T& object, ::Rcpp::traits::false_type ){
+	return wrap_dispatch_unknown_iterable__logical( object, 
+			typename ::Rcpp::traits::expands_to_logical<T>::type() );
+}
+
+template <typename T>
+SEXP wrap_dispatch_unknown_iterable__matrix_interface( const T& object, ::Rcpp::traits::true_type ){
+	SEXP res = PROTECT( 
+		wrap_dispatch_unknown_iterable__logical( object, 
+			typename ::Rcpp::traits::expands_to_logical<T>::type()
+		) 
+	) ;
+	SEXP dim = PROTECT( Rf_allocVector( INTSXP, 2) ) ;
+	INTEGER(dim)[0] = object.nrow() ;
+	INTEGER(dim)[1] = object.ncol() ;
+	Rf_setAttrib( res, Rf_install( "dim" ), dim ) ;
+	UNPROTECT(2) ;
+	return res ;
+}
+
+
 /**
  * Here we know for sure that type T has a T::iterator typedef
  * so we hope for the best and call the range based wrap with begin
@@ -421,8 +444,8 @@
  */
 template <typename T>
 SEXP wrap_dispatch_unknown_iterable(const T& object, ::Rcpp::traits::true_type){
-	return wrap_dispatch_unknown_iterable__logical( object, 
-		typename ::Rcpp::traits::expands_to_logical<T>::type() ) ;
+	return wrap_dispatch_unknown_iterable__matrix_interface( object, 
+		typename ::Rcpp::traits::matrix_interface<T>::type() ) ;
 }
 
 template <typename T, typename elem_type>

Modified: pkg/Rcpp/inst/include/Rcpp/internal/wrap_forward.h
===================================================================
--- pkg/Rcpp/inst/include/Rcpp/internal/wrap_forward.h	2010-07-05 11:45:11 UTC (rev 1781)
+++ pkg/Rcpp/inst/include/Rcpp/internal/wrap_forward.h	2010-07-05 13:17:42 UTC (rev 1782)
@@ -25,15 +25,22 @@
 
 #include <iterator>
 
-// this is a private header, included in RcppCommon.h
-// don't include it directly
-
 namespace Rcpp{
 	
 template<typename T> SEXP wrap_extra_steps( SEXP x ){
 	return x ;
-} 
+}
 
+namespace internal{
+	template <typename T>
+	class WrapIterableExtraStepsHelper {
+	public:
+		WrapIterableExtraStepsHelper( const T& ) {
+			Rprintf( "default WrapIterableExtraStepsHelper %s\n", DEMANGLE(T) ) ;
+		}
+		inline SEXP get( SEXP x ) const { return x ; }
+	} ;
+} // internal
 } // Rcpp
 
 #endif

Modified: pkg/Rcpp/inst/include/Rcpp/sugar/matrix/col.h
===================================================================
--- pkg/Rcpp/inst/include/Rcpp/sugar/matrix/col.h	2010-07-05 11:45:11 UTC (rev 1781)
+++ pkg/Rcpp/inst/include/Rcpp/sugar/matrix/col.h	2010-07-05 13:17:42 UTC (rev 1782)
@@ -37,10 +37,10 @@
 	Col( const LHS_TYPE& lhs) : nr( lhs.ncol() ), nc( lhs.ncol() ) {}
 	
 	inline int operator[]( int index ) const {
-		return Rcpp::internal::get_column( index, nr) ;
+		return Rcpp::internal::get_column( index, nr) + 1 ;
 	}
 	inline int operator()( int i, int j ) const {
-		return j ;
+		return j + 1 ;
 	}
 	
 	inline int size() const { return nr * nc ; }

Modified: pkg/Rcpp/inst/include/Rcpp/sugar/matrix/row.h
===================================================================
--- pkg/Rcpp/inst/include/Rcpp/sugar/matrix/row.h	2010-07-05 11:45:11 UTC (rev 1781)
+++ pkg/Rcpp/inst/include/Rcpp/sugar/matrix/row.h	2010-07-05 13:17:42 UTC (rev 1782)
@@ -26,7 +26,7 @@
 namespace sugar{
 
 template <int RTYPE, bool LHS_NA, typename LHS_T>
-class Row : public VectorBase< 
+class Row : public MatrixBase< 
 	INTSXP , 
 	false ,
 	Row<RTYPE,LHS_NA,LHS_T>
@@ -37,10 +37,10 @@
 	Row( const LHS_TYPE& lhs) : nr( lhs.nrow() ), nc( lhs.ncol() ) {}
 	
 	inline int operator[]( int index ) const {
-		return Rcpp::internal::get_line( index, nr) ;
+		return Rcpp::internal::get_line( index, nr) + 1;
 	}
 	inline int operator()( int i, int j ) const {
-		return i ;
+		return i + 1 ;
 	}
 	
 	inline int size() const { return nr * nc ; }

Added: pkg/Rcpp/inst/include/Rcpp/traits/matrix_interface.h
===================================================================
--- pkg/Rcpp/inst/include/Rcpp/traits/matrix_interface.h	                        (rev 0)
+++ pkg/Rcpp/inst/include/Rcpp/traits/matrix_interface.h	2010-07-05 13:17:42 UTC (rev 1782)
@@ -0,0 +1,61 @@
+// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-
+/* :tabSize=4:indentSize=4:noTabs=false:folding=explicit:collapseFolds=1: */
+//
+// matrix_interface.h: Rcpp R/C++ interface class library -- 
+//
+// Copyright (C) 2010	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__traits__matrix_interface_h
+#define Rcpp__traits__matrix_interface_h
+
+// helper trait to disambiguate things that want to be logical vectors
+// from containers of int
+
+namespace Rcpp{
+namespace traits{
+
+	template <int RTYPE>
+	struct matrix_interface__impl{} ;
+	
+	template <>
+	struct matrix_interface__impl<LGLSXP> {
+		struct r_matrix_interface{}; 
+	} ;
+
+	template<typename T>
+	class _has_matrix_interface_helper : __sfinae_types {
+      template<typename U> struct _Wrap_type { };
+
+      template<typename U>
+        static __one __test(_Wrap_type<typename U::r_matrix_interface>*);
+
+      template<typename U>
+        static __two __test(...);
+
+    public:
+      static const bool value = sizeof(__test<T>(0)) == 1;
+    };
+  
+  template<typename T> struct matrix_interface : 
+  	integral_constant<bool, _has_matrix_interface_helper<T>::value >{ };
+    
+    
+} 
+}
+
+#endif

Modified: pkg/Rcpp/inst/include/Rcpp/vector/MatrixBase.h
===================================================================
--- pkg/Rcpp/inst/include/Rcpp/vector/MatrixBase.h	2010-07-05 11:45:11 UTC (rev 1781)
+++ pkg/Rcpp/inst/include/Rcpp/vector/MatrixBase.h	2010-07-05 13:17:42 UTC (rev 1782)
@@ -29,6 +29,7 @@
 class MatrixBase : public traits::expands_to_logical__impl<RTYPE> {
 public:
 	struct r_type : traits::integral_constant<int,RTYPE>{} ;
+	struct r_matrix_interface {} ;
 	struct can_have_na : traits::integral_constant<bool,na>{} ;
 	typedef typename traits::storage_type<RTYPE>::type stored_type ;
 	

Modified: pkg/Rcpp/inst/include/RcppCommon.h
===================================================================
--- pkg/Rcpp/inst/include/RcppCommon.h	2010-07-05 11:45:11 UTC (rev 1781)
+++ pkg/Rcpp/inst/include/RcppCommon.h	2010-07-05 13:17:42 UTC (rev 1782)
@@ -227,6 +227,7 @@
 #include <Rcpp/traits/is_convertible.h>
 #include <Rcpp/traits/has_iterator.h>
 #include <Rcpp/traits/expands_to_logical.h>
+#include <Rcpp/traits/matrix_interface.h>
 #include <Rcpp/traits/has_na.h>
 #include <Rcpp/traits/storage_type.h>
 #include <Rcpp/traits/r_sexptype_traits.h>
@@ -258,6 +259,10 @@
 #include <Rcpp/traits/Exporter.h>
 #include <Rcpp/internal/r_coerce.h>
 #include <Rcpp/as.h>
+
+#include <Rcpp/vector/VectorBase.h>
+#include <Rcpp/vector/MatrixBase.h>
+
 #include <Rcpp/internal/wrap.h>
 
 #include <Rcpp/internal/ListInitialization.h>
@@ -269,8 +274,6 @@
 #include <Rcpp/preprocessor.h>
 #include <Rcpp/algo.h>
 
-#include <Rcpp/vector/VectorBase.h>
-#include <Rcpp/vector/MatrixBase.h>
 
 #include <Rcpp/sugar/sugar_forward.h>
 

Modified: pkg/Rcpp/inst/unitTests/runit.sugar.matrix.R
===================================================================
--- pkg/Rcpp/inst/unitTests/runit.sugar.matrix.R	2010-07-05 11:45:11 UTC (rev 1781)
+++ pkg/Rcpp/inst/unitTests/runit.sugar.matrix.R	2010-07-05 13:17:42 UTC (rev 1782)
@@ -1,4 +1,3 @@
-
 #!/usr/bin/r -t
 #
 # Copyright (C) 2010	Dirk Eddelbuettel and Romain Francois
@@ -18,48 +17,49 @@
 # You should have received a copy of the GNU General Public License
 # along with Rcpp.  If not, see <http://www.gnu.org/licenses/>.
 
-# does not yet work because of some compiler ambiguities
+.setUp <- function(){
+	if( ! exists( ".rcpp.sugar.matrix", globalenv() ) ){
+		# definition of all the functions at once
+		
+		sugar.functions <- list( 
+			"runit_outer" = list( 
+				signature( x = "numeric", y = "numeric" ), 
+'
+NumericVector xx(x) ;
+NumericVector yy(y);
+NumericMatrix m = outer( xx, yy, std::plus<double>() ) ;
+return m ;
+'		), 
+			"runit_row" = list( 
+				signature( x = "numeric" ), 
+'
+NumericMatrix xx(x) ;
+return List::create( 
+	_["row"] = row( xx ), 
+	_["col"] = col( xx )
+	) ;
+'
+			) 
+		)
+		
+		signatures <- lapply( sugar.functions, "[[", 1L )
+		bodies <- lapply( sugar.functions, "[[", 2L )
+		fx <- cxxfunction( signatures, bodies, plugin = "Rcpp")
+		getDynLib( fx ) # just forcing loading the dll now
+		assign( ".rcpp.sugar.matrix", fx, globalenv() )			
+	}
+}
+			
+test.sugar.outer <- function( ){
+	fx <- .rcpp.sugar.matrix$runit_outer
+	x <- 1:2
+	y <- 1:5
+	checkEquals( fx(x,y) , outer(x,y,"+") )
+}
 
-# .setUp <- function(){
-# 	if( ! exists( ".rcpp.sugar.matrix", globalenv() ) ){
-# 		# definition of all the functions at once
-# 		
-# 		sugar.functions <- list( 
-# 			"runit_outer" = list( 
-# 				signature( x = "numeric", y = "numeric" ), 
-# '
-# NumericVector xx(x) ;
-# NumericVector yy(y);
-# NumericMatrix m = outer( xx, yy, std::plus<double>() ) ;
-# return m ;
-# '		), 
-# 			"runit_row" = list( 
-# 				signature( x = "numeric" ), 
-# '
-# NumericMatrix xx(x) ;
-# return wrap( row( xx ) ) ;
-# '
-# 			) 
-# 		)
-# 		
-# 		signatures <- lapply( sugar.functions, "[[", 1L )
-# 		bodies <- lapply( sugar.functions, "[[", 2L )
-# 		fx <- cxxfunction( signatures, bodies, plugin = "Rcpp")
-# 		getDynLib( fx ) # just forcing loading the dll now
-# 		assign( ".rcpp.sugar", fx, globalenv() )			
-# 	}
-# }
-# 			
-# test.sugar.outer <- function( ){
-# 	fx <- .rcpp.sugar.matrix$runit_outer
-# 	x <- 1:2
-# 	y <- 1:5
-# 	checkEquals( fx(x,y) , outer(x,y,"+") )
-# }
-# 
-# test.sugar.row <- function( ){
-# 	fx <- .rcpp.sugar.matrix$runit_row
-# 	m <- matrix( 1:16, nc = 4 )
-# 	checkEquals( fx(m), row(m) ) 
-# }
-# 
+test.sugar.row <- function( ){
+	fx <- .rcpp.sugar.matrix$runit_row
+	m <- matrix( 1:16, nc = 4 )
+	checkEquals( fx(m), list( row = row(m), col = col(m) ) ) 
+}
+



More information about the Rcpp-commits mailing list