Skip to content

Commit 1157eb2

Browse files
faster as< std::vector<double> >
1 parent c934436 commit 1157eb2

File tree

3 files changed

+80
-36
lines changed

3 files changed

+80
-36
lines changed

ChangeLog

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
2013-09-16 Romain Francois <romain@r-enthusiasts.com>
2+
3+
* include/Rcpp/internal/Exporter.h : Specific handling of containers (std::vector,
4+
std::deque, and std::list so that we use their faster range constructor when
5+
we can, and so let the STL optimize how data is copied
6+
* include/Rcpp/api/meat/export.h : Implementation of the above
7+
18
2013-09-15 Dirk Eddelbuettel <edd@debian.org>
29

310
* inst/include/Rcpp/InputParameter.h (Rcpp): Add 'const' case

inst/include/Rcpp/api/meat/export.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,38 @@ namespace internal{
3535

3636

3737
} // namespace internal
38+
39+
namespace traits{
40+
41+
template < template <class, class> class ContainerTemplate, typename T > class ContainerExporter {
42+
public:
43+
typedef ContainerTemplate<T, std::allocator<T> > Container ;
44+
const static int RTYPE = Rcpp::traits::r_sexptype_traits<T>::rtype ;
45+
46+
ContainerExporter( SEXP x ) : object(x){}
47+
~ContainerExporter(){}
48+
49+
Container get(){
50+
if( TYPEOF(object) == RTYPE ){
51+
T* start = Rcpp::internal::r_vector_start<RTYPE>(object) ;
52+
return Container( start, start + Rf_length(object) ) ;
53+
}
54+
Container vec( ::Rf_length(object) );
55+
::Rcpp::internal::export_range( object, vec.begin() ) ;
56+
return vec ;
57+
}
58+
59+
private:
60+
SEXP object ;
61+
} ;
62+
template < template<class,class> class Container > struct container_exporter< Container, int >{
63+
typedef ContainerExporter< Container, int > type ;
64+
} ;
65+
template < template<class,class> class Container > struct container_exporter< Container, double >{
66+
typedef ContainerExporter< Container, double > type ;
67+
} ;
68+
69+
}
3870
} // namespace Rcpp
3971

4072
#endif

inst/include/Rcpp/internal/Exporter.h

Lines changed: 41 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*-
2-
/* :tabSize=4:indentSize=4:noTabs=false:folding=explicit:collapseFolds=1: */
32
//
43
// exporter.h: Rcpp R/C++ interface class library -- identify if a class has a nested iterator typedef
54
//
6-
// Copyright (C) 2010 - 2011 Dirk Eddelbuettel and Romain Francois
5+
// Copyright (C) 2010 - 2013 Dirk Eddelbuettel and Romain Francois
76
//
87
// This file is part of Rcpp.
98
//
@@ -26,33 +25,33 @@
2625
namespace Rcpp{
2726
namespace traits{
2827

29-
template <typename T> class Exporter{
30-
public:
31-
Exporter( SEXP x ) : t(x){}
32-
inline T get(){ return t ; }
33-
34-
private:
35-
T t ;
36-
} ;
37-
38-
template <typename T> class RangeExporter {
39-
public:
40-
typedef typename T::value_type r_export_type ;
41-
42-
RangeExporter( SEXP x ) : object(x){}
43-
~RangeExporter(){}
44-
45-
T get(){
46-
T vec( ::Rf_length(object) );
47-
::Rcpp::internal::export_range( object, vec.begin() ) ;
48-
return vec ;
49-
}
28+
template <typename T> class Exporter{
29+
public:
30+
Exporter( SEXP x ) : t(x){}
31+
inline T get(){ return t ; }
32+
33+
private:
34+
T t ;
35+
} ;
36+
37+
template <typename T> class RangeExporter {
38+
public:
39+
typedef typename T::value_type r_export_type ;
40+
41+
RangeExporter( SEXP x ) : object(x){}
42+
~RangeExporter(){}
43+
44+
T get(){
45+
T vec( ::Rf_length(object) );
46+
::Rcpp::internal::export_range( object, vec.begin() ) ;
47+
return vec ;
48+
}
49+
50+
private:
51+
SEXP object ;
52+
} ;
5053

51-
private:
52-
SEXP object ;
53-
} ;
54-
55-
template <typename T, typename value_type> class IndexingExporter {
54+
template <typename T, typename value_type> class IndexingExporter {
5655
public:
5756
typedef value_type r_export_type ;
5857

@@ -92,20 +91,26 @@ namespace Rcpp{
9291
SEXP object ;
9392
} ;
9493

95-
96-
template <typename T> class Exporter< std::vector<T> > : public RangeExporter< std::vector<T> > {
94+
template < template<class,class> class Container, typename T>
95+
struct container_exporter{
96+
typedef RangeExporter< Container<T, std::allocator<T> > > type ;
97+
} ;
98+
template < template<class,class> class Container > struct container_exporter< Container, int > ;
99+
template < template<class,class> class Container > struct container_exporter< Container, double > ;
100+
101+
template <typename T> class Exporter< std::vector<T> > : public container_exporter< std::vector, T>::type {
97102
public:
98-
Exporter(SEXP x) : RangeExporter< std::vector<T> >(x){}
103+
Exporter(SEXP x) : container_exporter< std::vector, T>::type(x){}
99104
};
100-
template <typename T> class Exporter< std::deque<T> > : public RangeExporter< std::deque<T> > {
105+
template <typename T> class Exporter< std::deque<T> > : public container_exporter< std::deque, T>::type {
101106
public:
102-
Exporter(SEXP x) : RangeExporter< std::deque<T> >(x){}
107+
Exporter(SEXP x) : container_exporter< std::deque, T>::type(x){}
103108
};
104-
template <typename T> class Exporter< std::list<T> > : public RangeExporter< std::list<T> > {
109+
template <typename T> class Exporter< std::list<T> > : public container_exporter< std::list, T>::type {
105110
public:
106-
Exporter(SEXP x) : RangeExporter< std::list<T> >(x){}
111+
Exporter(SEXP x) : container_exporter< std::list, T>::type(x){}
107112
};
108-
113+
109114
} // namespace traits
110115
} // namespace Rcpp
111116
#endif

0 commit comments

Comments
 (0)