On 3 April 2021 at 14:28, prezzemolo wrote:
| Hey.
| 
| I am wondering if there's some general guidance on what the 'right' options 
are to cleanly handle character arguments passed from R to Rcpp.
| 
| It is all rather simple: let's say I have a human-readable argument vector 
c("tree", "herb", "shrub") [It could also be a factor in R], which I can send 
to an Rcpp function along with other arguments for evaluation.
| What would be the cleanest way to define those arguments (plant types) in R 
to then have as little trouble sending them over to Rcpp for use in cases like 
if() statements?
| 
| 
| The use of enums comes to mind:
| 
| // beginningoffile
| enum class var_type { flower, tree };

That is a custom type you know / your C++ code knows. R and Rcpp have never
seen it --> extra work for you --> maybe simpler to do something else.

| RCPP_EXPOSED_ENUM_NODECL(var_type)
| 
| // [[Rcpp::export]]
| int charHandle1(var_type text_arg = var_type::flower) {

So don't do that.  Wrrite a 'mapper' function taking a std::string (or
Rcpp::CharacterVector or one of the equivalent ones, then map to your enum).

As the "fundamental theorem of software engineering" says "All problems in
computer science can be solved by another level of indirection" -- see for
example https://en.wikipedia.org/wiki/Indirection

|  if(text_arg == var_type::flower) {
|   Rcout << static_cast<int>(text_arg) << " says '0 (flower)'.\n";
|  } else if(text_arg == var_type::tree) {
|   Rcout << static_cast<int>(text_arg) << " says '1 (tree)'.\n";
|  }
|  return 0;
| }
| // endoffile
| 
| This however, doesn't seem to work. I understand R would have to know the 
var_type for it to work.
| Then I can do it simply by comparing the const char * argument. This will 
work, but the strcmp() comparison isn't very straightforward for someone who 
doesn't know C++ (and perhaps for some other reasons).

So make it const std::string text_arg = "flower" -- this lets you compare
via == (and loads of example packages do that.

-----------------------------------------------------------------------------
#include <Rcpp.h>

// [[Rcpp::export]]
void charHandle2(const std::string text_arg = "flower") {
    if (text_arg == "flower") {
        Rcpp::Rcout << text_arg << " says 'flower'.\n";
    } else if (text_arg == "tree") {
        Rcpp::Rcout << text_arg << " says 'tree'.\n";
    } else {
        Rcpp::Rcout << text_arg << " was incrompehensible.\n";
    }           
}

/*** R
charHandle2("flower")
charHandle2("tree")
charHandle2("banana")
*/
-----------------------------------------------------------------------------

That updated example yields:

> Rcpp::sourceCpp("/tmp/angelo.cpp")

> charHandle2("flower")
flower says 'flower'.

> charHandle2("tree")
tree says 'tree'.

> charHandle2("banana")
banana was incrompehensible.
> 

Hope this helps,  Dirk


| // [[Rcpp::export]]
| int charHandle2(const char* text_arg = "flower") {
|  if(strcmp(text_arg, "flower") == 0) {
|   Rcout << text_arg << " says 'flower'.\n";
|  } else if(strcmp(text_arg, "tree") == 0) {
|   Rcout << text_arg << " says 'tree'.\n";
|  }
|  return 0;
| }
| 
| I am looking for some good practice guidance on how to handle this safely and 
legibly to avoid sending people to function definitions. An argument could be 
made, for instance, that a list of plant type used as function arguments could 
be stored as factor in R and then sent and used in some way in Rcpp. What other 
options are there? To my best knowledge, support for enums is limited - I 
glanced over the vignettes and couldn't find any significant mention of enums 
(or factors, really), so I guess some other way of handling such cases should 
be taken. Has anyone dealt with such cases and has recommendations?
| 
| Regards,
| Angelo (Greetings from Genoa)
| _______________________________________________
| Rcpp-devel mailing list
| Rcpp-devel@lists.r-forge.r-project.org
| https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
-- 
https://dirk.eddelbuettel.com | @eddelbuettel | e...@debian.org
_______________________________________________
Rcpp-devel mailing list
Rcpp-devel@lists.r-forge.r-project.org
https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel

Reply via email to