[Rcpp-commits] r513 - in pkg: . inst/unitTests src src/Rcpp src/Rcpp/internal

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Sat Jan 30 12:37:54 CET 2010


Author: romain
Date: 2010-01-30 12:37:54 +0100 (Sat, 30 Jan 2010)
New Revision: 513

Added:
   pkg/src/Rcpp/internal/
   pkg/src/Rcpp/internal/wrap.h
Modified:
   pkg/cleanup
   pkg/inst/unitTests/runit.wrap.R
   pkg/src/CharacterVector.cpp
   pkg/src/Makevars
   pkg/src/Makevars.win
   pkg/src/RcppCommon.h
   pkg/src/wrap.cpp
Log:
fasten your seatbelt for template programming

Modified: pkg/cleanup
===================================================================
--- pkg/cleanup	2010-01-29 15:26:46 UTC (rev 512)
+++ pkg/cleanup	2010-01-30 11:37:54 UTC (rev 513)
@@ -2,6 +2,7 @@
 rm -f confdefs.h config.log config.status \
 	src/*.o src/*.so src/*.a src/*.d src/*.dll src/*.rc \
 	RcppSrc/*.o RcppSrc/*.a inst/Rcpp-version.txt \
+	inst/lib/Rcpp/internal/* \
 	inst/lib/Rcpp/* \
 	inst/lib/libRcpp.so inst/lib/Rcpp*.h inst/lib/libRcpp.a \
 	inst/doc/*.cpp inst/doc/*.hpp \
@@ -14,6 +15,7 @@
         inst/discovery/cxx0x.Rout \
 	src/Makedeps 
 rm -rf	autom4te.cache
+test -d inst/lib/Rcpp/internal && rmdir inst/lib/Rcpp/internal
 test -d inst/lib/Rcpp && rmdir inst/lib/Rcpp
 test -d inst/lib && rmdir inst/lib
 find . -name \*~ -exec rm {} \;

Modified: pkg/inst/unitTests/runit.wrap.R
===================================================================
--- pkg/inst/unitTests/runit.wrap.R	2010-01-29 15:26:46 UTC (rev 512)
+++ pkg/inst/unitTests/runit.wrap.R	2010-01-30 11:37:54 UTC (rev 513)
@@ -22,43 +22,45 @@
 }
 
 if( Rcpp:::capabilities()[["initializer lists"]] ){ 
-
-	test.wrap.initializerlist.int <- function(){
-		funx <- cfunction(signature(), '
-		return Rcpp::wrap( {0,1,2} ); 
-		', Rcpp=TRUE, verbose=FALSE,
-			cxxargs = "-std=c++0x")
-		checkEquals( funx(), 0:2, 
-			msg = "wrap( initializer_list<int> )" )
-	}
+      
+	# disabled for now
 	
-	test.wrap.initializerlist.double <- function(){
-		funx <- cfunction(signature(), '
-		return Rcpp::wrap( {0.0,1.0,2.0} ); 
-		', Rcpp=TRUE, verbose=FALSE,
-			cxxargs = "-std=c++0x")
-		checkEquals( funx(), as.numeric(0:2), 
-			msg = "wrap( initializer_list<double> )" )
-	}
+	# test.wrap.initializerlist.int <- function(){
+	# 	funx <- cfunction(signature(), '
+	# 	return Rcpp::wrap( {0,1,2} ); 
+	# 	', Rcpp=TRUE, verbose=FALSE,
+	# 		cxxargs = "-std=c++0x")
+	# 	checkEquals( funx(), 0:2, 
+	# 		msg = "wrap( initializer_list<int> )" )
+	# }
+	# 
+	# test.wrap.initializerlist.double <- function(){
+	# 	funx <- cfunction(signature(), '
+	# 	return Rcpp::wrap( {0.0,1.0,2.0} ); 
+	# 	', Rcpp=TRUE, verbose=FALSE,
+	# 		cxxargs = "-std=c++0x")
+	# 	checkEquals( funx(), as.numeric(0:2), 
+	# 		msg = "wrap( initializer_list<double> )" )
+	# }
+	# 
+	# test.wrap.initializerlist.bool <- function(){
+	# 	funx <- cfunction(signature(), '
+	# 	return Rcpp::wrap( {false, true, false} ); 
+	# 	', Rcpp=TRUE, verbose=FALSE,
+	# 		cxxargs = "-std=c++0x")
+	# 	checkEquals( funx(), c(FALSE, TRUE, FALSE), 
+	# 		msg = "wrap( initializer_list<bool> )" )
+	# }
+	# 
+	# test.wrap.initializerlist.Rbyte <- function(){
+	# 	funx <- cfunction(signature(), '
+	# 	return Rcpp::wrap( { (Rbyte)0, (Rbyte)1 } ); 
+	# 	', Rcpp=TRUE, verbose=FALSE,
+	# 		cxxargs = "-std=c++0x")
+	# 	checkEquals( funx(), as.raw(0:1), 
+	# 		msg = "wrap( initializer_list<Rbyte> )" )
+	# }
 	
-	test.wrap.initializerlist.bool <- function(){
-		funx <- cfunction(signature(), '
-		return Rcpp::wrap( {false, true, false} ); 
-		', Rcpp=TRUE, verbose=FALSE,
-			cxxargs = "-std=c++0x")
-		checkEquals( funx(), c(FALSE, TRUE, FALSE), 
-			msg = "wrap( initializer_list<bool> )" )
-	}
-	
-	test.wrap.initializerlist.Rbyte <- function(){
-		funx <- cfunction(signature(), '
-		return Rcpp::wrap( { (Rbyte)0, (Rbyte)1 } ); 
-		', Rcpp=TRUE, verbose=FALSE,
-			cxxargs = "-std=c++0x")
-		checkEquals( funx(), as.raw(0:1), 
-			msg = "wrap( initializer_list<Rbyte> )" )
-	}
-	
 	# test.wrap.initializerlist.RObject <- function(){
 	# 	funx <- cfunction(signature(), '
 	# 	return Rcpp::wrap( { Rcpp::wrap(1), Rcpp::wrap("foo"), Rcpp::wrap(1.0)  } ); 

Modified: pkg/src/CharacterVector.cpp
===================================================================
--- pkg/src/CharacterVector.cpp	2010-01-29 15:26:46 UTC (rev 512)
+++ pkg/src/CharacterVector.cpp	2010-01-30 11:37:54 UTC (rev 513)
@@ -105,11 +105,9 @@
 	return StringProxy(*this, offset(i,j) ) ;
 }
 
-// template<> SEXP wrap(const char& v){ return CharacterVector(v); }
-SEXP wrap(const char* const v){ return CharacterVector(v); }
-template<> SEXP wrap(const std::string & v){ return CharacterVector(v); }
-template<> SEXP wrap(const std::vector<std::string> & v){ return CharacterVector(v); }
+SEXP wrap(const char* const v){ return Rf_mkString(v); }
+// template<> SEXP<const char*>( const char* object ){
+// 	return Rf_mkString(object) ;
+// }
 
-
-
 } // namespace 

Modified: pkg/src/Makevars
===================================================================
--- pkg/src/Makevars	2010-01-29 15:26:46 UTC (rev 512)
+++ pkg/src/Makevars	2010-01-30 11:37:54 UTC (rev 513)
@@ -38,9 +38,11 @@
 userLibrary: 	$(USERLIB) $(USERLIBST)
 		- at if test ! -e $(USERDIR)$(R_ARCH); then mkdir -p $(USERDIR)$(R_ARCH); fi
 		- at if test ! -e $(USERDIR)$(R_ARCH)/Rcpp; then mkdir -p $(USERDIR)$(R_ARCH)/Rcpp; fi
+		- at if test ! -e $(USERDIR)$(R_ARCH)/Rcpp/internal; then mkdir -p $(USERDIR)$(R_ARCH)/Rcpp/internal; fi
 		cp $(USERLIB) $(USERDIR)$(R_ARCH)
 		cp Rcpp*.h $(USERDIR)$(R_ARCH)
 		cp Rcpp/*.h $(USERDIR)$(R_ARCH)/Rcpp
+		cp Rcpp/internal/*.h $(USERDIR)$(R_ARCH)/Rcpp/internal
 		cp $(USERLIBST) $(USERDIR)$(R_ARCH)
 		rm $(USERLIB) $(USERLIBST)
 

Modified: pkg/src/Makevars.win
===================================================================
--- pkg/src/Makevars.win	2010-01-29 15:26:46 UTC (rev 512)
+++ pkg/src/Makevars.win	2010-01-30 11:37:54 UTC (rev 513)
@@ -63,11 +63,12 @@
 		$(CXX) -shared -o $(PKGLIB) $(PKGOBJ) $(PKG_LIBS)
 
 $(USERLIB):	$(USEROBJ)
-		-mkdir -p $(USERDIR)/Rcpp 2>/dev/null
+		-mkdir -p $(USERDIR)/Rcpp/internal 2>/dev/null
 		ar r $(USERLIB) $(USEROBJ)
 		ranlib $(USERLIB)
-		cp -vax Rcp*.h $(USERDIR)
+		cp -vax *.h $(USERDIR)
 		cp -vax Rcpp/*.h $(USERDIR)/Rcpp
+		cp -vax Rcpp/internal/*.h $(USERDIR)/Rcpp/internal
 
 
 

Added: pkg/src/Rcpp/internal/wrap.h
===================================================================
--- pkg/src/Rcpp/internal/wrap.h	                        (rev 0)
+++ pkg/src/Rcpp/internal/wrap.h	2010-01-30 11:37:54 UTC (rev 513)
@@ -0,0 +1,289 @@
+// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*-
+/* :tabSize=4:indentSize=4:noTabs=false:folding=explicit:collapseFolds=1: */
+//
+// wrap.h: Rcpp R/C++ interface class library -- wrap implementations
+//
+// 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_internal_wrap_h
+#define Rcpp_internal_wrap_h
+
+// this is a private header, included in RcppCommon.h
+// don't include it directly
+
+namespace Rcpp{
+namespace internal{
+
+// pre-declaring wrap :
+template <typename T> SEXP wrap(const T& object) ;
+
+// {{{ information about R vectors
+// welcome to template metaprogramming !!
+
+// template that returns the SEXP type that is appropriate for 
+// the type T, this is allways VECSXP (lists) unless it is specialized
+template <typename T> struct r_sexptype{ enum{ rtype = VECSXP }; } ;
+template<> struct r_sexptype<int>{ enum{ rtype = INTSXP } ; } ;
+template<> struct r_sexptype<size_t>{ enum{ rtype = INTSXP } ; } ;
+template<> struct r_sexptype<double>{ enum{ rtype = REALSXP } ; } ;
+template<> struct r_sexptype<bool>{ enum{ rtype = LGLSXP } ; } ;
+template<> struct r_sexptype<std::string>{ enum{ rtype = STRSXP } ; } ;
+template<> struct r_sexptype<Rcomplex>{ enum{ rtype = CPLXSXP } ; } ;
+template<> struct r_sexptype<Rbyte>{ enum{ rtype = RAWSXP } ; } ;
+
+template<int RTYPE> struct storage_type{ typedef SEXP type ; } ;
+template<> struct storage_type<INTSXP>{  typedef int type ; } ;
+template<> struct storage_type<REALSXP>{ typedef double type ; } ;
+template<> struct storage_type<CPLXSXP>{ typedef Rcomplex type ; } ;
+template<> struct storage_type<RAWSXP>{ typedef Rbyte type ; } ;
+template<> struct storage_type<LGLSXP>{ typedef int type ; } ;
+
+template<int RTYPE, typename CTYPE> CTYPE* r_vector_start(SEXP x){ return static_cast<CTYPE*>(0) ; } ;
+template<> int* r_vector_start<INTSXP,int>(SEXP x) ; 
+template<> int* r_vector_start<LGLSXP,int>(SEXP x) ;
+template<> double* r_vector_start<REALSXP,double>(SEXP x) ;
+template<> Rbyte* r_vector_start<RAWSXP,Rbyte>(SEXP x) ; 
+template<> Rcomplex* r_vector_start<CPLXSXP,Rcomplex>(SEXP x) ;                         
+
+template <int RTYPE,typename CTYPE> CTYPE get_zero(){ return static_cast<CTYPE>(0) ; } ;
+template<> Rcomplex get_zero<CPLXSXP,Rcomplex>() ;
+
+// initializes a vector. The template does nothing because there is
+template<int RTYPE> void r_init_vector(SEXP x){
+	typedef storage_type<RTYPE> CTYPE ;
+	CTYPE* start=r_vector_start<RTYPE>(x) ;
+	std::fill( start, start + Rf_length(x), get_zero<RTYPE,CTYPE>(0) ) ;
+}
+// these are specifically overwritten so that they do nothing
+// - character vectors : already initialized with ""
+// - generic vectors   : already initialized with R_NilValue
+// - expression vectors: already initialized with R_NilValue
+template<> void r_init_vector<VECSXP>(SEXP x) ;
+template<> void r_init_vector<EXPRSXP>(SEXP x) ;
+template<> void r_init_vector<STRSXP>(SEXP x) ;
+// }}}
+
+// {{{ wrap_type_traits
+struct wrap_type_stl_container_tag{};    // stl type container, with begin and end methods
+struct wrap_type_primitive_tag{};        // primitive type
+struct wrap_type_unknown_tag{};          // unknown, not sure what to do with this type
+
+template <typename T> struct wrap_type_traits { typedef wrap_type_unknown_tag category; } ;
+
+// partial specialization for stl containers
+template <typename T> struct wrap_type_traits< std::vector<T> > { typedef wrap_type_stl_container_tag category ; } ;
+template <typename T> struct wrap_type_traits< std::set<T> > { typedef wrap_type_stl_container_tag category ; } ;
+template <typename T> struct wrap_type_traits< std::deque<T> > { typedef wrap_type_stl_container_tag category ; } ;
+// #ifdef HAS_INIT_LISTS
+// template <typename T> struct wrap_type_traits< std::initializer_list<T> > { typedef wrap_type_stl_container_tag category ; } ;
+// #endif
+
+template <> struct wrap_type_traits<int> { typedef wrap_type_primitive_tag category; } ;
+template <> struct wrap_type_traits<double> { typedef wrap_type_primitive_tag category; } ;
+template <> struct wrap_type_traits<Rbyte> { typedef wrap_type_primitive_tag category; } ;
+template <> struct wrap_type_traits<Rcomplex> { typedef wrap_type_primitive_tag category; } ;
+template <> struct wrap_type_traits<size_t> { typedef wrap_type_primitive_tag category; } ;
+template <> struct wrap_type_traits<bool> { typedef wrap_type_primitive_tag category; } ;
+template <> struct wrap_type_traits<std::string> { typedef wrap_type_primitive_tag category; } ;
+template <> struct wrap_type_traits<char> { typedef wrap_type_primitive_tag category; } ;
+// }}}
+
+// {{{ r_type_traits
+struct r_type_primitive_tag{} ;
+struct r_type_string_tag{} ;
+struct r_type_generic_tag{} ;
+struct r_type_bool_tag{} ;
+
+template <typename T> struct r_type_traits { typedef r_type_generic_tag category ; } ;
+template<> struct r_type_traits<int>{ typedef r_type_primitive_tag category ; } ;
+template<> struct r_type_traits<size_t>{ typedef r_type_primitive_tag category ; } ;
+template<> struct r_type_traits<double>{ typedef r_type_primitive_tag category ; } ;
+template<> struct r_type_traits<Rbyte>{ typedef r_type_primitive_tag category ; } ;
+template<> struct r_type_traits<Rcomplex>{ typedef r_type_primitive_tag category ; } ;
+template<> struct r_type_traits<bool>{ typedef r_type_bool_tag category ; } ;
+template<> struct r_type_traits<std::string>{ typedef r_type_string_tag category ; } ;
+template<> struct r_type_traits<char>{ typedef r_type_string_tag category ; } ;
+// }}}
+
+// {{{ range wrap 
+template <typename InputIterator, typename T>
+SEXP range_wrap_dispatch___impl( InputIterator first, InputIterator last, r_type_primitive_tag){ 
+	size_t size = std::distance( first, last ) ;
+	const int RTYPE = r_sexptype<T>::rtype ;
+	SEXP x = PROTECT( Rf_allocVector( RTYPE, size ) );
+	std::copy( first, last, r_vector_start<RTYPE, typename storage_type<RTYPE>::type >(x) ) ; 
+	UNPROTECT(1) ;
+	return x ;
+} ;
+
+template <typename InputIterator, typename T>
+SEXP range_wrap_dispatch___impl( InputIterator first, InputIterator last, r_type_bool_tag){ 
+	size_t size = std::distance( first, last ) ;
+	SEXP x = PROTECT( Rf_allocVector( LGLSXP, size ) );
+	std::transform( first, last, LOGICAL(x), bool_to_Rboolean ) ; 
+	UNPROTECT(1) ;
+	return x ;
+} ;
+
+
+// this implementation is used when T is not a primitive type
+// T needs to be wrappable though
+template <typename InputIterator, typename T>
+SEXP range_wrap_dispatch___impl( InputIterator first, InputIterator last, r_type_generic_tag ){ 
+	size_t size = std::distance( first, last ) ;
+	SEXP x = PROTECT( Rf_allocVector( VECSXP, size ) );
+	size_t i =0 ;
+	while( i < size ){
+		SET_VECTOR_ELT( x, i, wrap(*first) ) ;
+		i++ ;
+		++first ;
+	}
+	UNPROTECT(1) ;
+	return x ;
+} ;
+
+template<typename InputIterator, typename T>
+SEXP range_wrap_dispatch___impl( InputIterator first, InputIterator last, r_type_string_tag ){
+	size_t size = std::distance( first, last ) ;
+	SEXP x = PROTECT( Rf_allocVector( STRSXP, size ) ) ;
+	size_t i = 0 ;
+	std::string buffer ;
+	while( i < size ){
+		buffer = *first ;
+		SET_STRING_ELT( x, i, Rf_mkChar( buffer.c_str()) ) ;
+		i++ ;
+		++first ;
+	}
+	UNPROTECT(1) ;
+	return x ;
+}
+
+template<typename InputIterator, typename T>
+SEXP range_wrap_dispatch( InputIterator first, InputIterator last ){
+	return range_wrap_dispatch___impl<InputIterator,T>( first, last, typename r_type_traits<T>::category() ) ;
+}
+
+// we use the iterator trait to make the dispatch
+template <typename InputIterator>
+SEXP range_wrap(InputIterator first, InputIterator last){
+	return range_wrap_dispatch<InputIterator,typename std::iterator_traits<InputIterator>::value_type>( first, last ) ;
+}
+// }}}
+
+// {{{ primitive wrap (wrapping a single primitive value)
+
+// for 'easy' primitive types: int, double, Rbyte, Rcomplex
+template <typename T>
+SEXP primitive_wrap__impl( const T& object, r_type_primitive_tag ){
+	const int RTYPE = r_sexptype<T>::rtype ;
+	SEXP x = PROTECT( Rf_allocVector( RTYPE, 1 ) );
+	r_vector_start<RTYPE, typename storage_type<RTYPE>::type >(x)[0] = object ;
+	UNPROTECT(1);
+	return x;
+}
+
+// for bool
+template <typename T>
+SEXP primitive_wrap__impl( const T& object, r_type_bool_tag){
+	SEXP x = PROTECT( ::Rf_allocVector( LGLSXP, 1) );
+	LOGICAL(x)[0] = static_cast<int>(object);
+	UNPROTECT(1) ; /* x */
+	return x;
+}
+
+// for std::string
+template <typename T>
+SEXP primitive_wrap__impl( const T& object, r_type_string_tag){
+	SEXP x = PROTECT( ::Rf_allocVector( STRSXP, 1) ) ;
+	std::string y = object ; /* give a chance to implicit conversion */
+	SET_STRING_ELT( x, 0, Rf_mkChar(y.c_str()) ) ;
+	UNPROTECT(1) ;
+	return x; 
+}
+
+// T is a primitive type : int, bool, double, std::string, etc ...
+// wrapping this in an R vector of the appropriate type
+template <typename T>
+SEXP primitive_wrap(const T& object){
+	return primitive_wrap__impl( object, typename r_type_traits<T>::category() ) ;
+}
+// }}}
+
+// {{{ wrap dispatch
+// generic wrap for stl containers
+template <typename T> SEXP wrap_dispatch( const T& object, wrap_type_stl_container_tag ){
+	return range_wrap( object.begin(), object.end() ) ;
+}
+template <typename T> SEXP wrap_dispatch( const T& object, wrap_type_primitive_tag ){
+	return primitive_wrap( object ) ;
+}
+template <typename T> SEXP wrap_dispatch( const T& object, wrap_type_unknown_tag ){
+	SEXP x = object ;
+	return x ;
+}
+// }}}
+
+} // internal
+
+/* partial specialization */
+template <typename T> SEXP wrap(const T& object){
+	return internal::wrap_dispatch( object, typename internal::wrap_type_traits<T>::category() ) ;
+	//	SEXP x = object ; /* let implicit conversion work */
+	//	return x ;
+}
+// template<> SEXP wrap<const char*>( const char* object ) ;
+
+// {{{ // explicit instanciations (not needed)
+// template SEXP wrap<int>(const int& object) ;
+// template SEXP wrap<double>(const double& object) ;
+// template SEXP wrap<Rbyte>(const Rbyte& object) ;
+// template SEXP wrap<Rcomplex>(const Rcomplex& object) ;
+// template SEXP wrap<bool>(const bool& object) ;
+// template SEXP wrap<std::string>(const std::string& object) ;
+// template SEXP wrap< std::vector<int> >( const std::vector<int>& object ) ;
+// template SEXP wrap< std::vector<double> >( const std::vector<double>& object ) ;
+// template SEXP wrap< std::vector<Rbyte> >( const std::vector<Rbyte>& object ) ;
+// template SEXP wrap< std::vector<Rcomplex> >( const std::vector<Rcomplex>& object ) ;
+// template SEXP wrap< std::vector<bool> >( const std::vector<bool>& object ) ;
+// 
+// template SEXP wrap< std::set<int> >( const std::set<int>& object ) ;
+// template SEXP wrap< std::set<double> >( const std::set<double>& object ) ;
+// template SEXP wrap< std::set<Rbyte> >( const std::set<Rbyte>& object ) ;
+// 
+// template SEXP wrap< std::deque<int> >( const std::deque<int>& object ) ;
+// template SEXP wrap< std::deque<double> >( const std::deque<double>& object ) ;
+// template SEXP wrap< std::deque<Rbyte> >( const std::deque<Rbyte>& object ) ;
+// template SEXP wrap< std::deque<Rcomplex> >( const std::deque<Rcomplex>& object ) ;
+// template SEXP wrap< std::deque<bool> >( const std::deque<bool>& object ) ;
+// }}}
+
+#ifdef HAS_INIT_LISTS
+// template SEXP wrap< std::initializer_list<bool> >(const std::initializer_list<bool>& list) ;
+// template SEXP wrap< std::initializer_list<std::string> >(const std::initializer_list<std::string>& list ) ;
+// // template SEXP wrap< std::initializer_list<SEXP> >(const std::initializer_list<SEXP>& list ) ;
+// template SEXP wrap< std::initializer_list<Rbyte> >(const std::initializer_list<Rbyte>& list) ;
+// template SEXP wrap< std::initializer_list<double> >(const std::initializer_list<double>& list) ; 
+// template SEXP wrap< std::initializer_list<int> >(const std::initializer_list<int>& list) ; 
+#endif
+
+// special case
+SEXP wrap(const char* const v );
+
+} // Rcpp
+
+#endif

Modified: pkg/src/RcppCommon.h
===================================================================
--- pkg/src/RcppCommon.h	2010-01-29 15:26:46 UTC (rev 512)
+++ pkg/src/RcppCommon.h	2010-01-30 11:37:54 UTC (rev 513)
@@ -45,6 +45,7 @@
 #include <set>
 #include <stdexcept>
 #include <vector>
+#include <deque>
 #include <functional>
 #include <numeric>
 #include <algorithm>
@@ -189,179 +190,10 @@
 
 inline int int_to_RBoolean(int x){ return ( x == NA_INTEGER ) ? NA_LOGICAL : (x!=0); }
 
-template <typename T> SEXP wrap( const T& object){
-	SEXP x = object ; /* let implicit conversion work */
-	return x ;
-}
+} // namespace Rcpp
 
-template<> SEXP wrap(const int & v);
-template<> SEXP wrap(const size_t& v) ; 
-template<> SEXP wrap(const std::vector<int> & v);
-template<> SEXP wrap(const std::set<int> & v);
+#include <Rcpp/internal/wrap.h>
 
-template<> SEXP wrap(const double & v);
-template<> SEXP wrap(const std::vector<double> & v);
-template<> SEXP wrap(const std::set<double> & v);
-
-template<> SEXP wrap(const Rbyte & v);
-template<> SEXP wrap(const std::vector<Rbyte> & v);
-template<> SEXP wrap(const std::set<Rbyte> & v);
-
-
-template<> SEXP wrap(const bool & v); 
-template<> SEXP wrap(const std::vector<bool> & v);
-
-template<> SEXP wrap(const std::set<std::string> & v) ; 
-SEXP wrap(const char* const v );
-template<> SEXP wrap(const std::string & v) ;
-template<> SEXP wrap(const std::vector<std::string> & v) ;
-
-// range based wrappers
-
-namespace internal{
-
-// welcome to template metaprogramming !!
-	
-// template that returns the SEXP type that is appropriate for 
-// the type T, this is allways VECSXP (lists) unless it is specialized
-template <typename T> struct r_sexptype{ enum{ rtype = VECSXP }; } ;
-template<> struct r_sexptype<int>{ enum{ rtype = INTSXP } ; } ;
-template<> struct r_sexptype<size_t>{ enum{ rtype = INTSXP } ; } ;
-template<> struct r_sexptype<double>{ enum{ rtype = REALSXP } ; } ;
-template<> struct r_sexptype<bool>{ enum{ rtype = LGLSXP } ; } ;
-template<> struct r_sexptype<std::string>{ enum{ rtype = STRSXP } ; } ;
-template<> struct r_sexptype<Rcomplex>{ enum{ rtype = CPLXSXP } ; } ;
-
-template<int RTYPE> struct storage_type{ typedef SEXP type ; } ;
-template<> struct storage_type<INTSXP>{  typedef int type ; } ;
-template<> struct storage_type<REALSXP>{ typedef double type ; } ;
-template<> struct storage_type<CPLXSXP>{ typedef Rcomplex type ; } ;
-template<> struct storage_type<RAWSXP>{ typedef Rbyte type ; } ;
-template<> struct storage_type<LGLSXP>{ typedef int type ; } ;
-
-template<int RTYPE, typename CTYPE> CTYPE* r_vector_start(SEXP x){ return static_cast<CTYPE*>(0) ; } ;
-template<> int* r_vector_start<INTSXP,int>(SEXP x) ; 
-template<> int* r_vector_start<LGLSXP,int>(SEXP x) ;
-template<> double* r_vector_start<REALSXP,double>(SEXP x) ;
-template<> Rbyte* r_vector_start<RAWSXP,Rbyte>(SEXP x) ; 
-template<> Rcomplex* r_vector_start<CPLXSXP,Rcomplex>(SEXP x) ;                         
-
-template <int RTYPE,typename CTYPE> CTYPE get_zero(){ return static_cast<CTYPE>(0) ; } ;
-template<> Rcomplex get_zero<CPLXSXP,Rcomplex>() ;
-
-// initializes a vector. The template does nothing because there is
-template<int RTYPE> void r_init_vector(SEXP x){
-	typedef storage_type<RTYPE> CTYPE ;
-	CTYPE* start=r_vector_start<RTYPE>(x) ;
-	std::fill( start, start + Rf_length(x), get_zero<RTYPE,CTYPE>(0) ) ;
-}
-// these are specifically overwritten so that they do nothing
-// - character vectors : already initialized with ""
-// - generic vectors   : already initialized with R_NilValue
-// - expression vectors: already initialized with R_NilValue
-template<> void r_init_vector<VECSXP>(SEXP x) ;
-template<> void r_init_vector<EXPRSXP>(SEXP x) ;
-template<> void r_init_vector<STRSXP>(SEXP x) ;
-
-
-/* implementations of dispatch of range based wrap functions */
-
-struct r_type_primitive_tag{} ;
-struct r_type_string_tag{} ;
-struct r_type_generic_tag{} ;
-struct r_type_bool_tag{} ;
-
-template <typename T> struct r_type_traits { typedef r_type_generic_tag category ; } ;
-template<> struct r_type_traits<int>{ typedef r_type_primitive_tag category ; } ;
-template<> struct r_type_traits<double>{ typedef r_type_primitive_tag category ; } ;
-template<> struct r_type_traits<Rbyte>{ typedef r_type_primitive_tag category ; } ;
-template<> struct r_type_traits<Rcomplex>{ typedef r_type_primitive_tag category ; } ;
-
-template<> struct r_type_traits<bool>{ typedef r_type_bool_tag category ; } ;
-
-template<> struct r_type_traits<std::string>{ typedef r_type_string_tag category ; } ;
-
-template <typename InputIterator, typename T>
-SEXP range_wrap_dispatch___impl( InputIterator first, InputIterator last, r_type_primitive_tag){ 
-	size_t size = std::distance( first, last ) ;
-	const int RTYPE = r_sexptype<T>::rtype ;
-	SEXP x = PROTECT( Rf_allocVector( RTYPE, size ) );
-	std::copy( first, last, r_vector_start<RTYPE, storage_type<RTYPE> >(x) ) ; 
-	UNPROTECT(1) ;
-	return x ;
-} ;
-
-template <typename InputIterator, typename T>
-SEXP range_wrap_dispatch___impl( InputIterator first, InputIterator last, r_type_bool_tag){ 
-	size_t size = std::distance( first, last ) ;
-	SEXP x = PROTECT( Rf_allocVector( LGLSXP, size ) );
-	std::transform( first, last, LOGICAL(x), bool_to_Rboolean ) ; 
-	UNPROTECT(1) ;
-	return x ;
-} ;
-
-
-// this implementation is used when T is not a primitive type
-// T needs to be wrappable though
-template <typename InputIterator, typename T>
-SEXP range_wrap_dispatch___impl( InputIterator first, InputIterator last, r_type_generic_tag ){ 
-	size_t size = std::distance( first, last ) ;
-	SEXP x = PROTECT( Rf_allocVector( VECSXP, size ) );
-	size_t i =0 ;
-	while( i < size ){
-		SET_VECTOR_ELT( x, i, wrap(*first) ) ;
-		i++ ;
-		++first ;
-	}
-	UNPROTECT(1) ;
-	return x ;
-} ;
-
-template<typename InputIterator, typename T>
-SEXP range_wrap_dispatch___impl( InputIterator first, InputIterator last, r_type_string_tag ){
-	size_t size = std::distance( first, last ) ;
-	SEXP x = PROTECT( Rf_allocVector( STRSXP, size ) ) ;
-	size_t i = 0 ;
-	std::string buffer ;
-	while( i < size ){
-		buffer = *first ;
-		SET_STRING_ELT( x, i, Rf_mkChar( buffer.c_str()) ) ;
-		i++ ;
-		++first ;
-	}
-	UNPROTECT(1) ;
-	return x ;
-}
-
-template<typename InputIterator, typename T>
-SEXP range_wrap_dispatch( InputIterator first, InputIterator last ){
-	return range_wrap_dispatch___impl<InputIterator,T>( first, last, r_type_traits<T>::category() ) ;
-}
-
-// we use the iterator trait to make the dispatch
-template <typename InputIterator>
-SEXP range_wrap(InputIterator first, InputIterator last){
-	return range_wrap_dispatch<InputIterator,std::iterator_traits<InputIterator>::value_type>( first, last ) ;
-}
-
-}
-
-
-#ifdef HAS_INIT_LISTS
-inline template<> SEXP wrap(const std::initializer_list<bool>& list) { return internal::range_wrap(list.begin(), list.end() ); }
-inline template<> SEXP wrap(const std::initializer_list<std::string>& list ){ return internal::range_wrap(list.begin(), list.end()) ; }
-inline template<> SEXP wrap(const std::initializer_list<SEXP>& list ){ return internal::range_wrap(list.begin(), list.end() ) ; }
-inline template<> SEXP wrap(const std::initializer_list<Rbyte>& list) { return internal::range_wrap(list.begin(), list.end() ) ; }
-inline template<> SEXP wrap(const std::initializer_list<double>& list) { return internal::range_wrap( list.begin(), list.end() ); } 
-inline template<> SEXP wrap(const std::initializer_list<int>& list) { return internal::range_wrap( list.begin(), list.end() ) ;}
-#endif
-
-
-
-} // namespace Rcpp      
-
-
-
 #include <Rcpp/RObject.h>
 
 #endif

Modified: pkg/src/wrap.cpp
===================================================================
--- pkg/src/wrap.cpp	2010-01-29 15:26:46 UTC (rev 512)
+++ pkg/src/wrap.cpp	2010-01-30 11:37:54 UTC (rev 513)
@@ -63,122 +63,88 @@
 // 	return RObject(m_sexp) ;
 // }
  
-template<> SEXP wrap(const bool & v){
-    logTxt("RObject from bool\n");
-    LogicalVector o(Rf_ScalarLogical(v));
-    return o ;
-}
+// template<> SEXP wrap(const bool & v){
+//     logTxt("RObject from bool\n");
+//     LogicalVector o(Rf_ScalarLogical(v));
+//     return o ;
+// }
+// 
+// template<> SEXP wrap(const double & v){
+//     logTxt("RObject from double\n");
+//     NumericVector o(Rf_ScalarReal(v));
+//     return o ;
+// }
+// 
+// template<> SEXP wrap(const int & v){
+//     logTxt("RObject from int\n");
+//     IntegerVector o(Rf_ScalarInteger(v));
+//     return o ;
+// }
+// 
+// template<> SEXP wrap(const size_t & v){
+//     logTxt("RObject from size_t\n");
+//     IntegerVector o(Rf_ScalarInteger(static_cast<int>(v)));
+//     return o ;
+// }
+//    
+// template<> SEXP wrap(const Rbyte & v){
+//     logTxt("RObject from raw\n");
+//     RawVector o(Rf_ScalarRaw(v));
+//     return o ;
+// }
 
-template<> SEXP wrap(const double & v){
-    logTxt("RObject from double\n");
-    NumericVector o(Rf_ScalarReal(v));
-    return o ;
-}
+// template<> SEXP wrap(const std::vector<bool> & v){ return internal::range_wrap( v.begin(), v.end() ) ; }
+// template<> SEXP wrap(const std::vector<int> & v){ return internal::range_wrap( v.begin(), v.end() ) ; }
+// template<> SEXP wrap(const std::vector<double> & v){ return internal::range_wrap( v.begin(), v.end() ) ; }
+// template<> SEXP wrap(const std::vector<Rbyte> & v){ return internal::range_wrap( v.begin(), v.end() ) ; }
+// template<> SEXP wrap(const std::vector<std::string> & v){ return internal::range_wrap(v.begin(), v.end()); }
 
-template<> SEXP wrap(const int & v){
-    logTxt("RObject from int\n");
-    IntegerVector o(Rf_ScalarInteger(v));
-    return o ;
-}
-
-template<> SEXP wrap(const size_t & v){
-    logTxt("RObject from size_t\n");
-    IntegerVector o(Rf_ScalarInteger(static_cast<int>(v)));
-    return o ;
-}
-   
-template<> SEXP wrap(const Rbyte & v){
-    logTxt("RObject from raw\n");
-    RawVector o(Rf_ScalarRaw(v));
-    return o ;
-}
-
-template<> SEXP wrap(const std::vector<bool> & v){
-    logTxt("RObject from bool vector\n");
-    size_t n = v.size();
-    SEXP m_sexp = PROTECT( Rf_allocVector(LGLSXP, n) );
-    std::copy( v.begin(), v.end(), LOGICAL(m_sexp) ) ;
-    LogicalVector o(m_sexp) ;
-    UNPROTECT(1) ; /* m_sexp now preserved by o */
-    return o ;
-}
-
-template<> SEXP wrap(const std::vector<int> & v){
-    logTxt("RObject from int vector\n");
-    size_t n = v.size();
-    SEXP m_sexp = PROTECT( Rf_allocVector(INTSXP, n) );
-    std::copy( v.begin(), v.end(), INTEGER(m_sexp) ) ;
-    IntegerVector o(m_sexp) ;
-    UNPROTECT(1) ;
-    return o ;
-}
-
-template<> SEXP wrap(const std::vector<double> & v){
-    logTxt("RObject from double vector\n");
-    size_t n = v.size();
-    SEXP m_sexp = PROTECT( Rf_allocVector(REALSXP, n) );
-    std::copy( v.begin(), v.end(), REAL(m_sexp) ) ;
-    NumericVector o(m_sexp) ;
-    UNPROTECT(1) ;
-    return o ;
-}
-
-template<> SEXP wrap(const std::vector<Rbyte> & v){
-    logTxt("RObject from vector<Rbyte> \n");
-    size_t n = v.size();
-    SEXP m_sexp = PROTECT(Rf_allocVector(RAWSXP, n));
-    std::copy( v.begin(), v.end(), RAW(m_sexp) ) ;
-    RawVector o(m_sexp) ;
-    UNPROTECT(1) ;
-    return o ;
-}
-
 /* sets */
 
-template<> SEXP wrap(const std::set<int> & v){
-    logTxt("RObject from set<int>\n");
-    size_t n = v.size();
-    SEXP m_sexp = PROTECT( Rf_allocVector(INTSXP, n) );
-    copy( v.begin(), v.end(), INTEGER(m_sexp) ) ;
-    IntegerVector o(m_sexp) ;
-    UNPROTECT(1) ;
-    return o ;
-}
+// template<> SEXP wrap(const std::set<int> & v){
+//     logTxt("RObject from set<int>\n");
+//     size_t n = v.size();
+//     SEXP m_sexp = PROTECT( Rf_allocVector(INTSXP, n) );
+//     copy( v.begin(), v.end(), INTEGER(m_sexp) ) ;
+//     IntegerVector o(m_sexp) ;
+//     UNPROTECT(1) ;
+//     return o ;
+// }
+// 
+// template<> SEXP wrap(const std::set<double> & v){
+//     logTxt("RObject from set<double>\n");
+//     size_t n = v.size();
+//     SEXP m_sexp = PROTECT( Rf_allocVector(REALSXP, n) );
+//     copy( v.begin(), v.end(), REAL(m_sexp) ) ;
+//     NumericVector o(m_sexp) ;
+//     UNPROTECT(1) ;
+//     return o ;
+// }
+// 
+// template<> SEXP wrap(const std::set<Rbyte> & v){
+//     logTxt("RObject from set<Rbyte> \n");
+//     size_t n = v.size();
+//     SEXP m_sexp = PROTECT( Rf_allocVector(RAWSXP, n) );
+//     copy( v.begin(), v.end(), RAW(m_sexp) ) ;
+//     RawVector o(m_sexp) ;
+//     UNPROTECT(1) ;
+//     return o ;
+// }
+// 
+// template<> SEXP wrap(const std::set<std::string> & v){
+//     logTxt("RObject from set<string>\n");
+//     size_t n = v.size();
+//     SEXP m_sexp = PROTECT( Rf_allocVector(STRSXP, n) );
+//     size_t i=0;
+//     std::set<std::string>::iterator it = v.begin(); 
+//     while( i<n ){
+//     	SET_STRING_ELT(m_sexp, i, Rf_mkChar(it->c_str()));
+//     	i++ ;
+//     	it++; 
+//     }
+//     CharacterVector o(m_sexp) ;
+//     UNPROTECT(1) ;
+//     return o ;
+// }
 
-template<> SEXP wrap(const std::set<double> & v){
-    logTxt("RObject from set<double>\n");
-    size_t n = v.size();
-    SEXP m_sexp = PROTECT( Rf_allocVector(REALSXP, n) );
-    copy( v.begin(), v.end(), REAL(m_sexp) ) ;
-    NumericVector o(m_sexp) ;
-    UNPROTECT(1) ;
-    return o ;
-}
-
-template<> SEXP wrap(const std::set<Rbyte> & v){
-    logTxt("RObject from set<Rbyte> \n");
-    size_t n = v.size();
-    SEXP m_sexp = PROTECT( Rf_allocVector(RAWSXP, n) );
-    copy( v.begin(), v.end(), RAW(m_sexp) ) ;
-    RawVector o(m_sexp) ;
-    UNPROTECT(1) ;
-    return o ;
-}
-
-template<> SEXP wrap(const std::set<std::string> & v){
-    logTxt("RObject from set<string>\n");
-    size_t n = v.size();
-    SEXP m_sexp = PROTECT( Rf_allocVector(STRSXP, n) );
-    size_t i=0;
-    std::set<std::string>::iterator it = v.begin(); 
-    while( i<n ){
-    	SET_STRING_ELT(m_sexp, i, Rf_mkChar(it->c_str()));
-    	i++ ;
-    	it++; 
-    }
-    CharacterVector o(m_sexp) ;
-    UNPROTECT(1) ;
-    return o ;
-}
-
 } // namespace Rcpp



More information about the Rcpp-commits mailing list