Return result invisibly - c++

I’m trying to return a result (in fact, NULL) invisibly from a C++ function via Rcpp. Unfortunately I am unable to find out how to do this. My first attempt was to set R_Visible but this global variable is no longer exported; next, I tried calling do_invisible (the primitive that invisible calls) directly but, likewise, it’s not exported (and to be honest I’m unsure how to call it correctly anyway).
I then went the roundabout way, calling R’s base::invisible from Rcpp via an Rcpp::Function. My code is now something like this:
Rcpp::Function invisible = Rcpp::Environment("package:base")["invisible"];
// [[Rcpp::export]]
SEXP read_value(Rcpp::XPtr<std::vector<int>> x, int index) {
try {
return Rcpp::wrap(x->at(index));
} catch (std::out_of_range const&) {
return invisible(R_NilValue);
}
}
This compiles and executes. Unfortunately, the invisible call is simply ignored; when calling the function from R with an invalid index, it prints NULL. I would like it to print nothing.
For testing:
// [[Rcpp::export]]
Rcpp::XPtr<std::vector<int>> make_xvec() {
return Rcpp::XPtr<std::vector<int>>{new std::vector<int>{1, 2, 3}};
}
/*** R
xv = make_xvec()
read_value(xv, 1)
invisible(read_value(xv, 4)) # Works
read_value(xv, 4) # Doesn’t work
*/

Hm. "Ultimately" we always get SEXP .Call(id, SEXP a, SEXP b, ...) and that ends up (via Rcpp Attributes) with something like
R> rqdb::qdbConnect
function ()
{
.Call(`_rqdb_qdbConnect`)
}
<environment: namespace:rqdb>
R>
which when we call it gives us
R> qdbConnect()
[1] TRUE
R> invisible(qdbConnect())
R>
Can't you just wrap another layer at the R side and call it a day?
I think the key really is that a void function is possible, but the default is something as the SEXP. And C++ only has return so you need R for the invisible part.

Related

Is there a way to check the arity of Rcpp::Function?

I need to check the arity of a function in an Rcpp block at run time. What I would like to do is something akin to the following:
double loglikelihood(Rcpp::List data, Rcpp::List params, SEXP i, Rcpp::RObject custom_function) {
Rcpp::Function f = Rcpp::as<Rcpp::Function>(custom_function);
double res = 0.0;
if (arity(f) == 3) {
res = Rcpp::as<double>(f(data, param, i));
} else if (arity(f) == 2) {
res = Rcpp::as<double>(f(data, param));
}
return res;
}
However, the limited documentation I've seen for Rcpp does not seem to contain a function for checking the arity of an Rcpp::Function. Is there any way to do this?
The "limited documentation" (currently ten pdf vignettes alone) tells you, among other things, that all we have from R itself is .Call() returning SEXP and taking (an arbitrary number of) SEXP objects which can be a function. So all this ... goes back to the R API which may, or may not, have such an accessor which may or may not be public and supposed to be used by anybody but R itself.
These days we register compiled functions with R (typically in a file src/init.c or alike) where this number of argument is passed on as an second argument (beyond the function call name) when making the registration. Which suggests to me that it is not discoverable.
So I solved this using a workaround that is a little bit clunky but after giving it some serious thought, this is the least clunky of three methods I tried implementing.
The method I ended up going with is checking the arity of the function on the R side using methods::formalArgs, wrapping the (function, arity) pair in a list and passing that to the Rcpp function like so:
double loglikelihood(Rcpp::List data, Rcpp::List params,
SEXP i, Rcpp::RObject custom_function) {
Rcpp::List l = Rcpp::as<Rcpp::List>(custom_function);
Rcpp::Function f = Rcpp::as<Rcpp::Function>(l[0]);
int arity = l[1];
double res = 0.0;
if (arity == 3) {
res = Rcpp::as<double>(f(data, param, i));
} else if (arity == 2) {
res = Rcpp::as<double>(f(data, param));
}
return res;
}
As I mentioned, this is a bit clunky and it changes the signature of the funciton, which is not ideal. Another way of doing this would be to use the forgiveness-rather-than-permission approach and doing the control flow in a try-catch block, like so:
double loglikelihood(Rcpp::List data, Rcpp::List params,
SEXP i, Rcpp::RObject custom_function) {
Rcpp::Function f = Rcpp::as<Rcpp::Function>(custom_function);
double res = 0.0;
try {
res = Rcpp::as<double>(f(data, param, i));
} catch (const std::exception &e) {
res = Rcpp::as<double>(f(data, param));
}
return res;
}
This approach is less clunky, but the problem with it is that it also catches other exceptions that might arise within f and silences them so they aren't passed to the user. It is possible that there are more fine-grained exceptions defined in Rcpp that would be able to catch the specific error of passing too many parameters, but if so I haven't found it.
Lastly, we could pass methods::formalArgs to loglikelihood and query the arity just before we need to use it, but I think this approach is the clunkiest of the three, because it requires us to pass formalArgs around a lot.

Is there a way to dynamically change the return-type of a function in C++ based on function parameter values?

I am working on a problem that requires me to return different return-types based on my function parameter values that I provide.
I want to do something like this --
In the code below, doSomething() is an already existing function (used by a lot of clients) which takes mode as a function parameter, and returns std::list<ReturnType> already.
Based on the mode value, I had to create another sub-functionality which returns a shared_future<std::list<ReturnType>>.
How can I change this code so that it can return one of the two return types based on the mode value?
Note: ReturnType is a template typename which we are using for the entire class.
Code:
std::shared_future<std::list<ReturnType> > futureValue() {
return functionReturningSharedFuture();
}
std::list<ReturnType> listValue() {
return functionReturningList();
}
std::list<ReturnType> doSomething(int mode) {
if(mode == 1){
// new functionality that I added
return futureValue(); // This (obviously) errors out as of now
}
else{
// already there previously
return listValue();
}
}
int main() {
doSomething(1);
return 0;
}
How can I change this code so that it can return one of the two return types based on the mode value?
Constraints and Issues:
This issue could've been easily solved by function overloading if we provide an extra function parameter (like a true value), but that extra argument is not useful, since we are already using mode. Also, it isn't considered a good design to add variables which have almost no use.
One of the major constraints is that there are clients who are already using this doSomething() expect a std::list<ReturnType>, and so I cannot return boost::any or std::variant or anything similar.
I tried using std::enable_if, but it wasn't working out since we are getting the mode value at runtime.
We can't use template metaprogramming since that would change the way our function is being called on the client-side. Something that we can't afford to do.
Thank you.
This cannot be done.
You can only have one function with a given signature. If you have calling code that already expects this to return a std::list<ReturnType>, that's it; you're done.
If you could guarantee that all existing calling code looks like
auto l = obj.doSomething(1);
then you could potentially change the return type to something which would look like a std::list to any calling code. But if there's any calling code that looks like
std::list<ReturnType> l = obj.doSomething(1);
then that's off the table.
You probably need to rethink your design here.
From the example main, I see doSomething(1);, so maybe at the call site the value of the parameter mode is always known at compile-time. In this case, one option is that you make doSomething a template<int mode> function. I'm thinking about something like this:
#include <iostream>
#include <list>
#include <vector>
// assuming you cannot change this (actually you have changed it in you example, ...)
std::list<int> doSomething(int mode) {
std::cout << "already existing function\n";
return std::list<int>{1,2,3};
}
// then you can put this too
template<int N>
auto doSomething();
template<>
auto doSomething<10>() {
std::cout << "new function\n";
return std::vector<int>{1,2,3};
}
int main() {
auto x = doSomething(3);
auto y = doSomething<10>();
}
Probably another option would be to use a if constexpr intead of if and an auto/decltype(auto) return type in doSomething, but I haven't tried it.

create a instance within a #define macro

I wan't something like:
#define some_func(a) some_func(a, create_foo())
and then when using:
void loop() {
some_func(3);
some_func(40);
}
the Foo instance should only be created once for each line.
So in the above case, 2 times. And when loop is running again, it should not create the Foo instances again.
Is such a thing possible?
Here is the complete non working program:
The output should be 3, 40, 6, 80, 9, 120, 12, 160, ...
typedef struct {
int a;
} Foo;
Foo create_foo() {
return {0};
}
void some_func(int a, Foo &f) {
f.a += a;
Serial.println(f.a);
}
#define some_func(a) some_func(a, create_foo())
void setup() {
Serial.begin(9600);
}
void loop() {
some_func(3); // 3, 6, 9, 12
some_func(40); // 40, 80, 120, 160
}
Edit.
I tried to isolate the example to a bare minimum, but i'm shooting myself in the foot now. In the actual thing, I don't have a void as return type but a boolean.
So I try something like this now:
#define debounce(val) for(static auto d = create_debounce(); debounce(d, val), false;)
But that of course fails when used with:
int state = debounce(digitalRead(BUTTON_FIRE));
Cause the macro is not giving a value back so no assignment can happen.
So I need something like:
#define debounce(val) true; for(static auto d = create_debounce(); debounce(d, val), false;)
where true is the result of the create_debounce function.
So can poison it even more to make it possible? Here is the complete code:
// ----------------- L I B R A R Y . S T U F F -------------------------
#define debounce_delay 50
typedef struct {
int state;
int last_state;
unsigned long last_state_change_time;
} Debounce;
Debounce create_debounce() {
return {0, 0, 0L};
}
boolean debounce(Debounce &deb, int val) {
if (val != deb.last_state) {
deb.last_state_change_time = millis();
deb.last_state = val;
}
else if ((millis() - deb.last_state_change_time) > debounce_delay) {
deb.state = val;
}
return deb.state;
}
//#define debounce(val) for(static auto d = create_debounce(); debounce(d, val), false;)
#define debounce(val) true; for(static auto d = create_debounce(); debounce(d, val), false;)
// ----------------- S K E T C H -------------------------
#define BUTTON_FIRE 7
void setup() {
Serial.begin(9600);
}
void loop() {
int state = debounce(digitalRead(BUTTON_FIRE));
if (state == HIGH) {
Serial.println("HIGH");
}
else {
Serial.println("LOW");
}
}
If you are willing to get really ugly, you can accomplish practically anything. I'm only answering this because this is a brain teaser.
You can define the macro like this:
#define some_func(a) for(static auto f = create_foo(); some_func(a, f), false;)
Yes, this will work. In standard C++, the init clause of a for loop can contain a static variable declaration. So the variable will be initialized only once. Then the "condition" is the actual call to some_func followed by the comma operator with false, so the function is only execute once each time the for loop is entered.
Adapting your code from Arduino to standard C++, and simulating the four cycles, generated the same output you wanted. See it live.
Alternatively, if you want to appear slightly less cryptic (but why would you?), you can opt for this:
#define some_func(a) do {static auto f = create_foo(); some_func(a, f); } while(0)
Same thing really.
Alright, applying it to your actual problem calls for something different:
#define debounce(a) [](int v){static Debounce d = create_debounce(); \
return debounce(d, v); }(a)
This defines and immediately invokes a lambda. Since a lambda creates a unique closure type everywhere it appears in a program, this will create a unique static object for every expression you write debounce(...) in. An alternative is the GCC specific statement expression. But unlike a lambda, that is an extension. Which you may or may not want to use, YMMV.
When the loop is run again, then the Foo instances are created again, they are not restore from the previous run.
I suspect what you want to do is using a set of static variables. Or refactor your code for clarity.
This macro is not helping you in this matter, don't use it, use explicit variables and then you will see the lifetime of objects. A macro is not part of the compiler, but of the preprocessor.
Besides being ill-formed, your macro isn't useful for what you want because you're calling create_foo on each invocation.
You can use static variables:
void loop() {
static Foo f1, f2;
some_func(3, f1);
some_func(40, f2);
}
The first thing to note, is that your state is a boolean. This will save you a few bytes of RAM.
The next thing to point out is that you want to ignore changes to the input for a period of time; this means you don't need to store the "current" state; just the last state... which will end up being the same. This might not save you anything, since the 2 booleans and 1 boolean will likely just take a byte; but it gives the compiler a chance, and most importantly, makes things simpler.
With those 2 fairly minor improvements made, we get to the bigger ones. Don't use macros unless you really know what you're doing; and even then reconsider.
Arduino example code tends to offer them because someone thought it would make it easier to learn; but honestly, they don't. They're not a function, and your usage of it really isn't doing what you think it's doing. Arduino offer limited ways to debug it, so you can't actually tell that your state will ALWAYS be high, because the macro expansion is this:
int state = true;
for(static auto d = create_debounce();
debounce(d, val),
false;);
//New lines added for clarity.
Move it to a function; let the compiler optimise the code because it will ALWAYS do a better job than you as long as you write the code in a way that lets it.

Lua checkudata type C++

I've been to the end of Google and back trying to solve this problem.
I have a few userdata objects that I push from C++ to Lua.
I have a function that should get the X value of either a 2D or 3D object.
When I try to get the userdata object, taking into consideration that it could be either a 2D element or 3D object, I need to be able to get the X for whichever the user chooses.
Here is what I tried:
int getX(lua_State* L)
{
Object3D* a = static_cast<Object3D*>(luaL_checkudata(L, 1, "Object3D"));
if (!a)
{
Object2D* b = static_cast<Object2D*>(luaL_checkudata(L, 1, "Object2D"));
if (b)
{
lua_pushnumber(L, b:getX());
}
else
{
lua_pushnil(L);
}
}
else
{
lua_pushnumber(L, a:getX());
}
return 1;
}
Unfortunately if the userdata type is not Object3D, it fails and exits on an lua error without continuing to try Object2D.
Therefore, it will only work in the above code if the object being passed is of type Object3D.
luaL_testudata
void *luaL_testudata (lua_State *L, int arg, const char *tname);
This function works like luaL_checkudata, except that, when the test fails, it returns NULL instead of raising an error.
The lua(L)_check* functions throw Lua errors on failure, the lua(L)_to* functions return NULL. For whatever reason, this one deviates from the naming convention and is named lua(L)_test* instead, which makes it a bit harder to find.
Your code is incomplete and doesn't compile as-is so I can't be bothered to check, but if I'm not mistaken, just replacing luaL_checkudata with luaL_testudata should make it work as intended.
Solved by using rawequal to see which class the registry matches.

Comparing two values in Rcpp without casting to specific type

I seek to compare two generic R values in C++ using Rcpp. How can I compare two values without casting them to specific types in C++?
The code that explains my issue is as follows,
require("Rcpp")
require("inline")
src <- "return wrap(x1 == x2);"
fun <- cxxfunction(signature(x1 = "SEXP", x2 = "SEXP"), src, plugin = "Rcpp")
fun("a", "a")
to_cmp <- "a"
fun(to_cmp, to_cmp)
It now gives FALSE and TRUE where I want it to yield TRUE and TRUE.
Since my goal is to implement a data structure in C++ I would prefer to potential user defined == methods.
Possible approach
One approach that I tried is,
require("Rcpp")
src <- '
Language call("\`==\`", x1, x2);
return call.eval();
'
fun <- cxxfunction(signature(x1 = "SEXP", x2 = "SEXP"), src, plugin = "Rcpp")
fun("a", "a")
to_cmp <- "a"
fun(to_cmp, to_cmp)
However, when I run this I get Error: could not find function "`==`"
You are on the right track with using the generic SEXP input object tag. To get this to work one needs to use C++ templates in addition to TYPEOF(). The prior enables the correct vector creation in the comparison function to be hooked in with Rcpp sugar while the latter enables the correct check and dispatch to occur.
#include <Rcpp.h>
using namespace Rcpp;
template <int RTYPE>
Rcpp::LogicalVector compare_me(Rcpp::Vector<RTYPE> x, Rcpp::Vector<RTYPE> y) {
return x == y;
}
// [[Rcpp::export]]
Rcpp::LogicalVector compare_objects(SEXP x, SEXP y) {
if (TYPEOF(x) == TYPEOF(y)) {
switch (TYPEOF(x)) {
case INTSXP:
return compare_me<INTSXP>(x, y);
case REALSXP:
return compare_me<REALSXP>(x, y);
case STRSXP:
return compare_me<STRSXP>(x, y);
default:
Rcpp::stop("Type not supported");
}
} else {
Rcpp::stop("Objects are of different type");
}
// Never used, but necessary to avoid the compiler complaining
// about a missing return statement
return Rcpp::LogicalVector();
}
Example:
to_cmp <- "a"
compare_objects(to_cmp, to_cmp)
Output:
[1] TRUE
Also, the above is for use with Rcpp::sourceCpp(). I would encourage you to switch from using inline to using Rcpp::cppFunction() for function definitions as it allows you to focus on the computation and not the setup.