From f7686af4a3075f3748938cb30a0511d8d1ac43ed Mon Sep 17 00:00:00 2001 From: Qiang Kou Date: Sat, 12 Dec 2015 10:42:29 -0500 Subject: [PATCH] std::hash --- ChangeLog | 6 ++++++ inst/include/Rcpp/String.h | 20 ++++++++++++++++++++ inst/unitTests/cpp/wrap.cpp | 23 +++++++++++++++++++++++ inst/unitTests/runit.wrap.R | 12 ++++++++++++ 4 files changed, 61 insertions(+) diff --git a/ChangeLog b/ChangeLog index cf5e96a22..c33a71026 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2015-12-12 Qiang Kou + + * inst/include/Rcpp/String.h: std::hash + * inst/unitTests/cpp/wrap.cpp: Unit tests + * inst/unitTests/runit.wrap.R: Unit tests + 2015-12-04 Qiang Kou * inst/include/Rcpp/vector/Matrix.h: Add math operators between matrix diff --git a/inst/include/Rcpp/String.h b/inst/include/Rcpp/String.h index b3bf1c8f1..4a92cd7f0 100644 --- a/inst/include/Rcpp/String.h +++ b/inst/include/Rcpp/String.h @@ -556,4 +556,24 @@ namespace Rcpp { } // Rcpp +/** hash can be in std or std::tr1 */ +#if defined(RCPP_USING_CXX11) || defined(HAS_TR1) +namespace std +{ +#ifndef RCPP_USING_CXX11 +namespace tr1 { +#endif + template <> + struct hash + { + size_t operator()(const Rcpp::String & s) const{ + return hash()(s.get_cstring()); + } + }; +#ifndef RCPP_USING_CXX11 +} +#endif +} +#endif + #endif diff --git a/inst/unitTests/cpp/wrap.cpp b/inst/unitTests/cpp/wrap.cpp index 93acd9a94..1f42f62d5 100644 --- a/inst/unitTests/cpp/wrap.cpp +++ b/inst/unitTests/cpp/wrap.cpp @@ -168,6 +168,10 @@ SEXP nonnull_const_char(){ return wrap(p) ; } +#ifdef RCPP_USING_CXX11 +// [[Rcpp::plugins(cpp11)]] +#endif + // [[Rcpp::export]] IntegerVector unordered_map_string_int(){ RCPP_UNORDERED_MAP< std::string, int > m ; @@ -177,6 +181,25 @@ IntegerVector unordered_map_string_int(){ return wrap(m); } +// [[Rcpp::export]] +IntegerVector unordered_map_rcpp_string_int(StringVector v){ + RCPP_UNORDERED_MAP< String, int > m ; + m[v[0]] = 200; + m[v[1]] = 100; + m[v[2]] = 300; + return wrap(m); +} + +// [[Rcpp::export]] +LogicalVector unordered_set_rcpp_string(StringVector x) { + RCPP_UNORDERED_SET seen; + LogicalVector out(x.size()); + for (int i = 0; i < x.size(); i++) { + out[i] = !seen.insert(x[i]).second; + } + return out; +} + // [[Rcpp::export]] NumericVector unordered_map_string_double(){ RCPP_UNORDERED_MAP m ; diff --git a/inst/unitTests/runit.wrap.R b/inst/unitTests/runit.wrap.R index 6898f8700..ff7894523 100644 --- a/inst/unitTests/runit.wrap.R +++ b/inst/unitTests/runit.wrap.R @@ -108,6 +108,18 @@ if (.runThisTest) { checkEquals( res[["c"]], 300L, msg = "wrap( tr1::unordered_map) " ) } + test.wrap.unordered.map.rcpp.string.int <- function(){ + res <- unordered_map_rcpp_string_int(c("a", "b", "c")) + checkEquals( res[["a"]], 200L, msg = "wrap( tr1::unordered_map) " ) + checkEquals( res[["b"]], 100L, msg = "wrap( tr1::unordered_map) " ) + checkEquals( res[["c"]], 300L, msg = "wrap( tr1::unordered_map) " ) + } + + test.unordered.set.rcpp.string <- function(){ + checkEquals(unordered_set_rcpp_string(c("a", "b", "c", "b")), + c(FALSE, FALSE, FALSE, TRUE), msg = "wrap( tr1::unordered_set) " ) + } + test.wrap.unordered.map.string.double <- function(){ res <- unordered_map_string_double() checkEquals( res[["a"]], 200, msg = "wrap( tr1::unordered_map) " )