Skip to content

Commit 93b8e69

Browse files
committed
Merge branch 'attributes-fixes'
Conflicts: ChangeLog
2 parents 8df8741 + d925320 commit 93b8e69

File tree

3 files changed

+67
-15
lines changed

3 files changed

+67
-15
lines changed

ChangeLog

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,15 @@
1111

1212
* inst/include/Rcpp/traits/un_pointer.h: fix bug in un_pointer for object<T>
1313

14-
2014-02-16 JJ Allaire <[email protected]>
14+
2014-02-17 Kevin Ushey <[email protected]>
15+
16+
* src/attributes.cpp: Fix attributes behavior with
17+
::create, and also add an option for a default constructor
18+
(e.g. NumericVector v = NumericVector(10)) gives a default
19+
value of 'numeric(10)' at the R level). Also make NAs
20+
keep their type when exposed to R.
21+
22+
2014-02-16 JJ Allaire <[email protected]>
1523

1624
* src/attributes.cpp Replace (incorrect) call to
1725
Rcpp::internal::jumpToTop with Rf_onintr

inst/NEWS.Rd

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,13 @@
2121
\item Changes in Rcpp Attributes
2222
\itemize{
2323
\item Fix issue preventing packages with Rcpp::interfaces attribute
24-
from compiling.
24+
from compiling.
25+
\item Fix behavior with attributes parsing of ::create for default
26+
arguments, and also allow constructors of a given size
27+
(e.g. NumericVector v = NumericVector(10)) gives a default
28+
value of 'numeric(10)' at the R level). Also make NAs preserve
29+
type when exported to R (e.g. NA_STRING as a default argument
30+
maps to NA_character_ at the R level)
2531
}
2632
\item Changes in Rcpp modules
2733
\itemize{

src/attributes.cpp

Lines changed: 51 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2016,16 +2016,18 @@ namespace attributes {
20162016

20172017
std::string args = cppArg.substr(createLoc + create.length());
20182018
if (type == "CharacterVector")
2019-
return "character" + args;
2020-
else if (type == "IntegerVector")
2021-
return "integer" + args;
2022-
else if (type == "NumericVector")
2023-
return "numeric" + args;
2024-
else
2025-
return std::string();
2019+
return "as.character( c" + args + ")";
2020+
if (type == "IntegerVector")
2021+
return "as.integer( c" + args + ")";
2022+
if (type == "NumericVector")
2023+
return "as.numeric( c" + args + ")";
2024+
if (type == "LogicalVector")
2025+
return "as.logical( c" + args + ")";
2026+
2027+
return std::string();
20262028
}
20272029

2028-
// convert a C++ Matrix to an R argument (returns emtpy string
2030+
// convert a C++ Matrix to an R argument (returns empty string
20292031
// if no conversion possible)
20302032
std::string cppMatrixArgToRArg(const std::string& cppArg) {
20312033

@@ -2041,7 +2043,7 @@ namespace attributes {
20412043
return "matrix" + args;
20422044
}
20432045

2044-
// convert a C++ literal to an R argument (returns emtpy string
2046+
// convert a C++ literal to an R argument (returns empty string
20452047
// if no conversion possible)
20462048
std::string cppLiteralArgToRArg(const std::string& cppArg) {
20472049
if (cppArg == "true")
@@ -2050,14 +2052,45 @@ namespace attributes {
20502052
return "FALSE";
20512053
else if (cppArg == "R_NilValue")
20522054
return "NULL";
2053-
else if (cppArg == "NA_STRING" || cppArg == "NA_INTEGER" ||
2054-
cppArg == "NA_LOGICAL" || cppArg == "NA_REAL") {
2055-
return "NA";
2056-
}
2055+
else if (cppArg == "NA_STRING")
2056+
return "NA_character_";
2057+
else if (cppArg == "NA_INTEGER")
2058+
return "NA_integer_";
2059+
else if (cppArg == "NA_LOGICAL")
2060+
return "NA_integer_";
2061+
else if (cppArg == "NA_REAL")
2062+
return "NA_real_";
20572063
else
20582064
return std::string();
20592065
}
20602066

2067+
// convert an Rcpp container constructor to an R argument
2068+
// (returns empty string if no conversion possible)
2069+
std::string cppConstructorArgToRArg(const std::string& cppArg) {
2070+
2071+
// map Rcpp containers to R default initializers
2072+
static std::map<std::string, std::string> RcppContainerToR;
2073+
RcppContainerToR.insert(std::make_pair("NumericVector", "numeric"));
2074+
RcppContainerToR.insert(std::make_pair("DoubleVector", "numeric"));
2075+
RcppContainerToR.insert(std::make_pair("CharacterVector", "character"));
2076+
RcppContainerToR.insert(std::make_pair("IntegerVector", "integer"));
2077+
RcppContainerToR.insert(std::make_pair("LogicalVector", "logical"));
2078+
RcppContainerToR.insert(std::make_pair("ComplexVector", "complex"));
2079+
2080+
// for each entry in the map above, see if we find it; if we do,
2081+
// return the R version
2082+
typedef std::map<std::string, std::string>::const_iterator Iterator;
2083+
for (Iterator it = RcppContainerToR.begin(); it != RcppContainerToR.end(); ++it) {
2084+
size_t loc = cppArg.find(it->first);
2085+
if (loc != std::string::npos) {
2086+
return it->second + cppArg.substr(it->first.size(), std::string::npos);
2087+
}
2088+
}
2089+
2090+
return std::string();
2091+
2092+
}
2093+
20612094
// convert a C++ argument value to an R argument value (returns empty
20622095
// string if no conversion is possible)
20632096
std::string cppArgToRArg(const std::string& type,
@@ -2087,6 +2120,11 @@ namespace attributes {
20872120
if (!rArg.empty())
20882121
return rArg;
20892122

2123+
// try for a constructor arg
2124+
rArg = cppConstructorArgToRArg(cppArg);
2125+
if (!rArg.empty())
2126+
return rArg;
2127+
20902128
// couldn't parse the arg
20912129
return std::string();
20922130
}

0 commit comments

Comments
 (0)