[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