From d6bff86ce0507ac15b816f143525c0d4a9069b5d Mon Sep 17 00:00:00 2001 From: "Daniel C. Dillon" Date: Sun, 5 Nov 2017 11:29:36 -0600 Subject: [PATCH 1/4] Added inject/extract functions to Rcpp::Vector for bitwise copying of C++ data into R vectors. --- inst/include/Rcpp/vector/Vector.h | 61 ++++++++++++++++++++++++ inst/unitTests/cpp/Vector.cpp | 78 +++++++++++++++++++++++++++++++ inst/unitTests/runit.Vector.R | 32 +++++++++++++ 3 files changed, 171 insertions(+) diff --git a/inst/include/Rcpp/vector/Vector.h b/inst/include/Rcpp/vector/Vector.h index 141bce006..94e5f24cc 100644 --- a/inst/include/Rcpp/vector/Vector.h +++ b/inst/include/Rcpp/vector/Vector.h @@ -373,6 +373,67 @@ class Vector : inline NameProxy operator()( const std::string& name ) const { return NameProxy( const_cast(*this), name ) ; } + + template< typename T > + inline typename traits::enable_if< + traits::is_arithmetic< stored_type >::value + && sizeof(T) <= sizeof(stored_type), void >::type + inject(R_xlen_t i, const T &val) + { + memcpy(&cache.ref(offset(i)), &val, sizeof(T)); + } + + template< typename T > + inline typename traits::enable_if< + traits::is_arithmetic< stored_type >::value + && sizeof(T) == sizeof(stored_type), void >::type + inject(R_xlen_t start, const T *val, std::size_t len) + { + memcpy(&cache.ref(offset(start)), val, sizeof(T) * len); + } + + template< typename T > + inline typename traits::enable_if< + traits::is_arithmetic< stored_type >::value + && sizeof(T) < sizeof(stored_type), void >::type + inject(R_xlen_t start, const T *val, std::size_t len) + { + for (std::size_t i = 0; i < len; ++i) + { + inject(start + i, *(val + i)); + } + } + + template< typename T > + inline typename traits::enable_if< + traits::is_arithmetic< stored_type >::value + && sizeof(stored_type) >= sizeof(T), void >::type + extract(R_xlen_t i, T &val) + { + memcpy(&val, &cache.ref(offset(i)), sizeof(T)); + } + + template< typename T > + inline typename traits::enable_if< + traits::is_arithmetic< stored_type >::value + && sizeof(stored_type) == sizeof(T), void >::type + extract(R_xlen_t start, T *val, std::size_t len) + { + memcpy(val, &cache.ref(offset(start)), + sizeof(stored_type) * len); + } + + template< typename T > + inline typename traits::enable_if< + traits::is_arithmetic< stored_type >::value + && sizeof(T) < sizeof(stored_type), void >::type + extract(R_xlen_t start, T *val, std::size_t len) + { + for (std::size_t i = 0; i < len; ++i) + { + extract(start + i, *(val + i)); + } + } inline operator RObject() const { return RObject( Storage::get__() ); diff --git a/inst/unitTests/cpp/Vector.cpp b/inst/unitTests/cpp/Vector.cpp index 2c47b7e7a..4c07c86e6 100644 --- a/inst/unitTests/cpp/Vector.cpp +++ b/inst/unitTests/cpp/Vector.cpp @@ -848,3 +848,81 @@ String vec_print_integer(IntegerVector v) { IntegerVector vec_subset(IntegerVector x, IntegerVector y) { return x[y - 1]; } + +// [[Rcpp::export]] +NumericVector vec_inject() +{ + int64_t i = 12345; + int64_t ii = 9876543210; + + NumericVector v(2); + + v.inject(0, i); + v.inject(1, ii); + + return v; +} + +// [[Rcpp::export]] +NumericVector vec_inject_array() +{ + const int64_t arr[] = { 12345, 9876543210 }; + + NumericVector v(2); + v.inject(0, arr, 2); + + return v; +} + +// [[Rcpp::export]] +NumericVector vec_inject_array_smaller() +{ + const int32_t arr[] = { 12345, 98765432 }; + + NumericVector v(2); + v.inject(0, arr, 2); + + return v; +} + +// [[Rcpp::export]] +NumericVector vec_extract(NumericVector v) +{ + int64_t i; + int64_t ii; + + v.extract(0, i); + v.extract(1, ii); + + NumericVector v2(2); + v2.inject(0, i); + v2.inject(1, ii); + + return v2; +} + +// [[Rcpp::export]] +NumericVector vec_extract_array(NumericVector v) +{ + int64_t i[2]; + + v.extract(0, i, 2); + + NumericVector v2(2); + v2.inject(0, i, 2); + + return v2; +} + +// [[Rcpp::export]] +NumericVector vec_extract_array_smaller(NumericVector v) +{ + int32_t i[2]; + + v.extract(0, i, 2); + + NumericVector v2(2); + v2.inject(0, i, 2); + + return v2; +} \ No newline at end of file diff --git a/inst/unitTests/runit.Vector.R b/inst/unitTests/runit.Vector.R index fdb0b0e58..25deb3c4f 100644 --- a/inst/unitTests/runit.Vector.R +++ b/inst/unitTests/runit.Vector.R @@ -755,5 +755,37 @@ if (.runThisTest) { gctorture(FALSE) checkEquals(x[y], z) } + + test.numeric.vector.inject <- function() { + v <- vec_inject() + checkIdentical(v, c(6.0992403979101885879e-320, + 4.8796606997276282938e-314)) + } + + test.numeric.vector.inject.array <- function() { + v <- vec_inject_array() + checkIdentical(v, c(6.0992403979101885879e-320, + 4.8796606997276282938e-314)) + } + + test.numeric.vector.inject.extract.array.smaller <- function() { + v <- vec_inject_array_smaller() + v2 <- vec_extract_array_smaller(v) + checkIdentical(v, v2) + } + + test.numeric.vector.extract <- function() { + v <- c(6.0992403979101885879e-320, 4.8796606997276282938e-314) + + res <- vec_extract(v) + checkIdentical(v, res) + } + + test.numeric.vector.extract_array <- function() { + v <- c(6.0992403979101885879e-320, 4.8796606997276282938e-314) + + res <- vec_extract_array(v) + checkIdentical(v, res) + } } From 6349a927e8ad0420a61281245cce4e77c5fe5b71 Mon Sep 17 00:00:00 2001 From: "Daniel C. Dillon" Date: Sun, 5 Nov 2017 11:35:55 -0600 Subject: [PATCH 2/4] Added ChangeLog entries. --- ChangeLog | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index 334f12794..0fdddac43 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2017-11-05 Daniel C. Dillon + + * inst/include/Rcpp/vector/Vector.h: Added inject() and extract() + functions to allow insertion and retrieval of raw C++ data into + and from Rcpp::Vector of arithmetic types. + * inst/unitTests/cpp/Vector.cpp: Unit tests + * inst/unitTests/runit.Vector.R: Unit tests + 2017-11-04 Dirk Eddelbuettel * vignettes/Rcpp-FAQ.Rmd: Add 'skip_final_break: true' toggle From 3256abc235fa5648aa99c025a77e6c5afb4ec11e Mon Sep 17 00:00:00 2001 From: "Daniel C. Dillon" Date: Sun, 5 Nov 2017 11:47:47 -0600 Subject: [PATCH 3/4] Updated NEWS.Rd as well. --- inst/NEWS.Rd | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/inst/NEWS.Rd b/inst/NEWS.Rd index 406332c4e..fa403387d 100644 --- a/inst/NEWS.Rd +++ b/inst/NEWS.Rd @@ -13,7 +13,9 @@ allocating one (Kirill Müller in \ghpr{763}). \item New \code{DateVector} and \code{DatetimeVector} classes are now the default fully deprecating the old classes as announced one year ago. - + \item New \code{Vector::inject()} and \code{Vector::extract()} functions + for copying raw byte data from C++ into an element or elements in + \code{Vector}. } \item Changes in Rcpp Package: \itemize{ From db372617359b0993882b400354f752b85db5309a Mon Sep 17 00:00:00 2001 From: Dirk Eddelbuettel Date: Mon, 6 Nov 2017 09:44:13 -0600 Subject: [PATCH 4/4] whitespace and indentation cleanup, use std::memcpy --- inst/include/Rcpp/vector/Vector.h | 44 +++++++++++--------------- inst/unitTests/cpp/Vector.cpp | 52 ++++++++++++++----------------- 2 files changed, 41 insertions(+), 55 deletions(-) diff --git a/inst/include/Rcpp/vector/Vector.h b/inst/include/Rcpp/vector/Vector.h index 94e5f24cc..eadafaa71 100644 --- a/inst/include/Rcpp/vector/Vector.h +++ b/inst/include/Rcpp/vector/Vector.h @@ -373,64 +373,56 @@ class Vector : inline NameProxy operator()( const std::string& name ) const { return NameProxy( const_cast(*this), name ) ; } - + template< typename T > inline typename traits::enable_if< traits::is_arithmetic< stored_type >::value && sizeof(T) <= sizeof(stored_type), void >::type - inject(R_xlen_t i, const T &val) - { - memcpy(&cache.ref(offset(i)), &val, sizeof(T)); + inject(R_xlen_t i, const T &val) { + std::memcpy(&cache.ref(offset(i)), &val, sizeof(T)); } - + template< typename T > inline typename traits::enable_if< traits::is_arithmetic< stored_type >::value && sizeof(T) == sizeof(stored_type), void >::type - inject(R_xlen_t start, const T *val, std::size_t len) - { - memcpy(&cache.ref(offset(start)), val, sizeof(T) * len); + inject(R_xlen_t start, const T *val, std::size_t len) { + std::memcpy(&cache.ref(offset(start)), val, sizeof(T) * len); } - + template< typename T > inline typename traits::enable_if< traits::is_arithmetic< stored_type >::value && sizeof(T) < sizeof(stored_type), void >::type - inject(R_xlen_t start, const T *val, std::size_t len) - { - for (std::size_t i = 0; i < len; ++i) - { + inject(R_xlen_t start, const T *val, std::size_t len) { + for (std::size_t i = 0; i < len; ++i) { inject(start + i, *(val + i)); } } - + template< typename T > inline typename traits::enable_if< traits::is_arithmetic< stored_type >::value && sizeof(stored_type) >= sizeof(T), void >::type - extract(R_xlen_t i, T &val) - { - memcpy(&val, &cache.ref(offset(i)), sizeof(T)); + extract(R_xlen_t i, T &val) { + std::memcpy(&val, &cache.ref(offset(i)), sizeof(T)); } - + template< typename T > inline typename traits::enable_if< traits::is_arithmetic< stored_type >::value && sizeof(stored_type) == sizeof(T), void >::type - extract(R_xlen_t start, T *val, std::size_t len) - { - memcpy(val, &cache.ref(offset(start)), + extract(R_xlen_t start, T *val, std::size_t len) { + std::memcpy(val, &cache.ref(offset(start)), sizeof(stored_type) * len); } - + template< typename T > inline typename traits::enable_if< traits::is_arithmetic< stored_type >::value && sizeof(T) < sizeof(stored_type), void >::type - extract(R_xlen_t start, T *val, std::size_t len) - { - for (std::size_t i = 0; i < len; ++i) - { + extract(R_xlen_t start, T *val, std::size_t len) { + for (std::size_t i = 0; i < len; ++i) { extract(start + i, *(val + i)); } } diff --git a/inst/unitTests/cpp/Vector.cpp b/inst/unitTests/cpp/Vector.cpp index 4c07c86e6..db7100247 100644 --- a/inst/unitTests/cpp/Vector.cpp +++ b/inst/unitTests/cpp/Vector.cpp @@ -850,79 +850,73 @@ IntegerVector vec_subset(IntegerVector x, IntegerVector y) { } // [[Rcpp::export]] -NumericVector vec_inject() -{ +NumericVector vec_inject() { int64_t i = 12345; int64_t ii = 9876543210; - + NumericVector v(2); - + v.inject(0, i); v.inject(1, ii); - + return v; } // [[Rcpp::export]] -NumericVector vec_inject_array() -{ +NumericVector vec_inject_array() { const int64_t arr[] = { 12345, 9876543210 }; - + NumericVector v(2); v.inject(0, arr, 2); - + return v; } // [[Rcpp::export]] -NumericVector vec_inject_array_smaller() -{ +NumericVector vec_inject_array_smaller() { const int32_t arr[] = { 12345, 98765432 }; - + NumericVector v(2); v.inject(0, arr, 2); - + return v; } // [[Rcpp::export]] -NumericVector vec_extract(NumericVector v) -{ +NumericVector vec_extract(NumericVector v) { int64_t i; int64_t ii; - + v.extract(0, i); v.extract(1, ii); - + NumericVector v2(2); v2.inject(0, i); v2.inject(1, ii); - + return v2; } // [[Rcpp::export]] -NumericVector vec_extract_array(NumericVector v) -{ +NumericVector vec_extract_array(NumericVector v) { int64_t i[2]; - + v.extract(0, i, 2); - + NumericVector v2(2); v2.inject(0, i, 2); - + return v2; } // [[Rcpp::export]] -NumericVector vec_extract_array_smaller(NumericVector v) -{ +NumericVector vec_extract_array_smaller(NumericVector v) { int32_t i[2]; - + v.extract(0, i, 2); - + NumericVector v2(2); v2.inject(0, i, 2); - + return v2; -} \ No newline at end of file +} pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy