Rcpp modules: Validator function for exposed constructors with same number of parameters - rcpp

I would like to expose a C++ class with Rcpp modules that has two constructors with the same number of parameters. As documented in the Rcpp modules vignette, this can be achieved by using a validator function as the second argument to .constructor with the type
typedef bool (*ValidConstructor)(SEXP*,int);
Could somebody provide an example of how it is supposed to be used? In the vignette, there is only a TODO note that an example should be included there.

To follow up on nrussell's answer, you might want to generate the validators from templates, i.e.
template <typename T0, typename T1>
bool typed_valid( SEXP* args, int nargs ){
return nargs == 2 && Rcpp::is<T0>(args[0]) && Rcpp::is<T1>(args[1]) ;
}
which you would use as:
.constructor<int, int>( & typed_valid<int,int> )
obviously the typed_valid function template is straightforward to generalize with variadic templates.

With the disclaimer that I haven't personally used this before, the following appears to work:
#include <Rcpp.h>
using namespace Rcpp;
class Example {
public:
Example(int x_, int y_)
: x(x_), y(y_)
{
Rcout << __PRETTY_FUNCTION__ << "\n";
}
Example(std::string x_, std::string y_)
: x(x_.size()), y(y_.size())
{
Rcout << __PRETTY_FUNCTION__ << "\n";
}
int add() const
{ return x + y; }
private:
int x, y;
};
bool validate_int_int(SEXP* args, int nargs)
{ return TYPEOF(args[0]) == INTSXP && TYPEOF(args[1]) == INTSXP; }
bool validate_string_string(SEXP* args, int nargs)
{ return TYPEOF(args[0]) == STRSXP && TYPEOF(args[1]) == STRSXP; }
RCPP_MODULE(ExampleMod) {
class_<Example>("Example")
.constructor<int, int>(
"(int, int) constructor",
validate_int_int
)
.constructor<std::string, std::string>(
"(string, string) constructor",
validate_string_string
)
.method("add", &Example::add)
;
}
Testing from R,
ex.int <- new(Example, 1L, 2L)
# Example::Example(int, int)
ex.string <- new(Example, "one", "two")
# Example::Example(std::string, std::string)
ex.int$add()
# [1] 3
ex.string$add()
# [1] 6
In each of validate_int_int and validate_string_string we are just testing the input SEXP types against the signatures of their corresponding constructors.

Following the footsteps of previous answers, I found there is a chance that a universal validator function might exist by using variadic template in cpp.
The implementation is shorter than I have expected though there are many technical details beyond the scope of this post.
template <typename... Types>
bool universal_validator(SEXP* args, int nargs) {
return universal_validator<Types...>(args, nargs, 0);
}
template <typename T = void, typename... Types>
bool universal_validator(SEXP* args, int nargs, int idx) {
if (idx>=nargs) return false;
// optional type traits
typedef typename Rcpp::traits::remove_const_and_reference<T>::type _Tp;
return Rcpp::is<_Tp>(args[idx]) && universal_validator<Types...>(args, nargs, idx+1);
}
template <>
bool universal_validator<>(SEXP* args, int nargs, int idx) {
return nargs == idx;
}
The usage of this universal_validator is quite simple. Given the Example class, the constructors in the RCPP_MODULE will become as follows.
RCPP_MODULE(example_module) {
Rcpp::class_<Example>("Example")
.constructor<int, int>("(int, int) constructor",
universal_validator<int, int>)
.constructor<std::string, std::string> ("(string, string) constructor",
universal_validator<std::string, std::string>)
.method("add", &Example::add)
;
}
Just put the same argument types as the constructor in the validator template, e.g. universal_validator<int, int> will do the job. And this shall work as long as Rcpp::is<T> is defined for any type T.
The source code from github
SEXP newInstance( SEXP* args, int nargs ) indicates that the validator must check the types of SEXP* and nargs simultaneously. That's why not only the type but also the index of SEXP* is also checked in all functions.

Related

Converting all variadic arguments into a single std::string via move semantics

I have a class that contains a lambda function that looks like this:
class Foo {
private:
inline static std::string text{};
public:
template<typename...T>
inline static auto func = [](T&&...args) mutable throw() {
text += std::string(args...);
};
void show() {
std::cout << text << '\n';
}
};
My intended use would be something like this:
int main() {
Foo bar;
bar.func<std::string, int, std::string>( "Hello, I am", 39, "years old!");
bar.show();
return 0;
}
I want the templated variadic lambda to take in any type of parameter that is a basic type such as string, char*, char[], int, float, double, etc... and to convert all of them into a single std::string that will be stored within the class.
When I run my code as such:
int main() {
Foo bar;
bar.func<string>( "Hello world!");
bar.show();
return 0;
}
Everything compiles fine, however, when I begin to add in various types such as the example from the intended use above, it fails to compile. Microsoft Visual Studio is giving me a C2400 compiler error: cannot convert from initialize list to std::string. No constructor could take the source type, or constructor overload resolution was ambiguous...
I believe I understand why it is ambiguous as that's not so much the issue. My question is what would be the proper and efficient way of using "move semantics or perfect forwarding"? I'm trying to avoid a bunch of copies of temporaries.
You could use fold expressions:
template<typename...T>
inline static auto func = [](T&&...args) mutable throw() {
text += (toString(args) + ...);
};
where toString is defined as:
template<class T>
std::string toString(T&& t){
if constexpr (std::is_arithmetic_v<std::decay_t<T>>)
return std::to_string(std::forward<T>(t));
else
return std::forward<T>(t);
}
you can extend toString to handle all types you need to convert to string.
Demo

Using c++11's std::async inside an abstract base class

Why doesn't making threads like this work inside of an abstract base class? I'm trying to abstract away all of the multithreading details for users who derive from this base class. I don't understand why it says "no type named 'type'" when I clearly write that callbackSquare returns type int.
#include <iostream>
#include <future>
#include <vector>
class ABC{
public:
std::vector<std::future<int> > m_results;
ABC(){};
~ABC(){};
virtual int callbackSquare(int& a) = 0;
void doStuffWithCallBack();
};
void ABC::doStuffWithCallBack(){
for(int i = 0; i < 10; ++i)
m_results.push_back(std::async(&ABC::callbackSquare, this, i));
for(int j = 0; j < 10; ++j)
std::cout << m_results[j].get() << "\n";
}
class Derived : public ABC {
Derived() : ABC() {};
~Derived(){};
int callbackSquare(int& a) {return a * a;};
};
int main(int argc, char **argv)
{
std::cout << "testing\n";
return 0;
}
The strange errors I'm getting are:
/usr/include/c++/5/future:1709:67: required from 'std::future<typename std::result_of<_Functor(_ArgTypes ...)>::type> std::async(std::launch, _Fn&&, _Args&& ...) [with _Fn = int (ABC::*)(int&); _Args = {ABC*, int&}; typename std::result_of<_Functor(_ArgTypes ...)>::type = int]'
/usr/include/c++/5/future:1725:19: required from 'std::future<typename std::result_of<_Functor(_ArgTypes ...)>::type> std::async(_Fn&&, _Args&& ...) [with _Fn = int (ABC::*)(int&); _Args = {ABC*, int&}; typename std::result_of<_Functor(_ArgTypes ...)>::type = int]'
/home/taylor/Documents/ssmworkspace/callbacktest/main.cpp:16:69: required from here
/usr/include/c++/5/functional:1505:61: error: no type named 'type' in 'class std::result_of<std::_Mem_fn<int (ABC::*)(int&)>(ABC*, int)>'
typedef typename result_of<_Callable(_Args...)>::type result_type;
^
/usr/include/c++/5/functional:1526:9: error: no type named 'type' in 'class std::result_of<std::_Mem_fn<int (ABC::*)(int&)>(ABC*, int)>'
_M_invoke(_Index_tuple<_Indices...>)
Your problem can be reproduced with any function that accepts a reference:
#include <future>
int f(int& a)
{
return a * a;
}
int main()
{
int i = 42;
auto r = std::async(f, i);
}
Accepting a reference in your code is risky since the variable will be modified by the loop iteration, creating a data race because the called function also accesses the variable.
Change the function to accept the input parameter by value, or call std::async by passing std::ref(i) or std::cref(i) (in case the function accepts a const reference) if you acknowledge the risk.

C++11 std::thread accepting function with rvalue parameter

I have some homework, and I have troubles understanding, (probably) how passing parameters to std::thread constructor works.
Assume following code (I deleted unneeded parts)
template<typename T, typename Task>
class Scheduler
{
private:
typedef std::unordered_map<std::size_t, T> Results;
class Solver
{
public:
Solver(Task&& task) : m_thread(&Solver::thread_function, std::move(task))
{
m_thread.detach();
}
Solver(Solver&& solver) = default; // required for vector::emplace_back
~Solver() = default;
private:
void thread_function(Task&& task)
{
task();
}
std::thread m_thread;
};
public:
Scheduler() = default;
~Scheduler() = default;
void add_task(Task&& task)
{
m_solvers.emplace_back(std::move(task));
}
private:
std::vector<Solver> m_solvers;
};
template<typename T>
struct Ftor
{
explicit Ftor(const T& t) : data(t) { }
T operator()() { std::cout << "Computed" << std::endl; return data; }
T data;
};
int main()
{
Scheduler<int, Ftor<int>> scheduler_ftor;
Scheduler<int, std::function<int(void)>> scheduler_lambda;
Ftor<int> s(5);
scheduler_ftor.add_task(std::move(s));
scheduler_lambda.add_task([](){ std::cout << "Computed" << std::endl; return 1; });
}
Why it doesn't compile?
MVS2015 is complaining about
functional(1195): error C2064: term does not evaluate to a function taking 1 arguments
functional(1195): note: class does not define an 'operator()' or a user defined conversion operator to a pointer-to-function or reference-to-function that takes appropriate number of arguments
note: while compiling class template member function 'Scheduler<int,Ftor<int> >::Solver::Solver(Task &&)'
While G++ 4.9.2
functional: In instantiation of ‘struct std::_Bind_simple<std::_Mem_fn<void (Scheduler<int, Ftor<int> >::Solver::*)(Ftor<int>&&)>(Ftor<int>)>’:
required from ‘void Scheduler<T, Task>::add_task(Task&&) [with T = int; Task = Ftor<int>]’
functional:1665:61: error: no type named ‘type’ in ‘class std::result_of<std::_Mem_fn<void (Scheduler<int, Ftor<int> >::Solver::*)(Ftor<int>&&)>(Ftor<int>)>’
typedef typename result_of<_Callable(_Args...)>::type result_type;
I suppose there are some problems with std::moving to std::thread.
If you use member function as first thread argument, second argument supposed to be this pointer, pointing to the object to which member function could be called to
UPDATE
Good discussion here
Start thread with member function
I don't follow your code, but addressing the question, a extrapolated answer will be( most of the code is psuedocode)
lets assume that there is a function int test(int name).
thread t0;
t0 = thread(test,32);
thread t1(test,43);
Passing a argument to function.
int temp = 0;
int testfunc(int& q)
{
cout<<q;
}
thread t1;
t1 = thread(testfunc,ref(temp));
In short, you just pass the name of the function that must be run in the thread as the first argument, and the functions parameters follow it in same order as they are in the function definition, for passing by reference you can use the ref() wrapper.See the below example.
#include <iostream>
#include <thread>
#include <string>
using namespace std;
void test(int a,int &a,string test)
{
\\do something
}
int main()
{
int test1 = 0;
string tt = "hello";
thread t1;
t1 = thread(23,&test1,tt);
t1.detach();
return 0;
}
if you are wondering about the use of join() and detach(), refer to this thread: When should I use std::thread::detach?, refer to my answer post in that thread.

Templated arguments causes inability to "Find function"

I'm trying to write some code that can execute a class member function in a separate thread, but with some added code for checking odds and ends before and after the thread has executed.
For this I'm using the std::bind and std::thread functionality of c++11 in VS2012.
All this works well if I fix the arguments the class member function can have to e.g. void*, but if I try to template that, I get an error.
Overview of Code
I have a simple class containing two functions, which will be executed in a thread. They differ in arguments and name.
The class I'm creating has a templated constructor and a function, which executes the functions of the previous class, but with the ability to perform it's own checks/notifications if the thread does/does not finish.
Finally the main function is simply to test the code.
The Code
Include Part:
#include <iostream>
#include <memory>
#include <thread>
#include <functional>
using namespace std;
Class to be executed:
class k1
{
public:
k1( int nVal = 0 ) : _val(nVal){};
~k1(){};
void doFunc( void * pParam ){
cout << "Val in class = " << _val << ", param = " << pParam << "\n";
}
void doFunc2( float pParam ){
cout << "Val in class = " << _val << ", param = " << pParam << "\n";
}
int _val;
};
typedef shared_ptr<k1> PK;
Thread Handle Class
class H
{
public:
void controlFunction( std::function<void(void)> callRef ){
cout << "Before calling\n";
callRef();
cout << "After calling\n";
}
template<class T, typename ParamType> // Constructor for any type of class function - void * parameter as only input
H( void(T::* pFunction)(ParamType *), T * pClass, ParamType pParam ){
std::function<void(void)> _call = std::bind( pFunction, pClass, pParam );
_thread = shared_ptr<std::thread>( new thread( &H::controlFunction, this, _call ));
}
~H( void ){
_thread->join();
}
shared_ptr<thread> _thread;
};
typedef shared_ptr<H> PH;
Main Function:
int main(int argc, char* argv[])
{
PK k = make_shared<k1>( 12 );
int i1 = 2;
float f1 = 1.0f;
PH p = PH( new H(&k1::doFunc, k.get(), &i1 ));
PH p2 = PH( new H(&k1::doFunc2, k.get(), f1 ));
return 0;
}
The error that comes out is:
error C2660: 'H::H' : function does not take 3 arguments
Thanks in advance!
/Henrik
I'm guessing that you get the error on the second line where you create a H object taking k1::doFunc2 as argument. The probable reason for the error is because k1::doFunc2 doesn't take a pointer for argument, while the member function pointer argument in the H constructor expects it to.
There is also some problems with the first line, when you declare the p variable. This is because then the ParamType template type can be deduced to be either int or int*. The reason for this is because the member function pointer have ParamType *, while the third argument to the constructor uses non-pointer ParamType but you pass a pointer here (&i1).

Can't invoke or assign a std::function that has an rvalue reference as an argument (Visual C++)

Seems like Visual C++'s std::function<> doesn't handle functions with rvalue refs as arguments. Can anyone suggest a workaround?
#include <functional>
using namespace std;
class Object { };
void f(Object&&) { }
auto g = [](Object&&){ };
function<void(Object&&)> h;
int main()
{
Object o;
f(move(o));
g(move(o));
// Uncomment any one of the following lines, and we get an error from the instantiation
// of std::function: "error C2664: You cannot bind an lvalue to an rvalue reference"
//h(move(o));
//h = g;
//h = f;
return 0;
}
This is Visual Studio 2010. I am not using /Za (so it is not this problem).
Update after some research: The code compiles in Clang, so I am pretty sure it is a Microsoft bug. It might be this one, fixed in VC11: 649274
Correction to the update: The MS bug is not fixed in VC11. From the link:
our first opportunity will be the "out of band" release between VC11 and VC12 that Herb Sutter
announced at the GoingNative 2012 conference.
I'm not sure what workaround you'd like here. Assuming you cannot change the call expression of the function object and the target signature, you can wrap the rvalue reference and pass the wrapped object (a temporary) via const ref.
Essentially, the call expands to: f( wrap(move(o)) );
I suspect there's a problem with perfect forwarding, because binding i = bind(&f); does not work; therefore I've introduced an intermediate step performing perfect forwarding, such that the call is resolved to: f( move( (Object&)wrap( move(o) ) ) );
#include <iostream>
#include <functional>
using namespace std;
struct Object { int m; };
// target function with fixed signature (assuming we cannot change that)
void f(Object&& p) { p.m = 42; std::cout << p.m; };
// was surprised I didn't find any method to chain functions in the StdLib
// so here's my own:
template < typename F1, typename F2, typename P1 >
auto chain2(F1 f1, F2 f2, P1&& p1)
-> decltype( f1(f2( std::forward<P1>(p1) )) )
{
return f1( f2( std::forward<P1>(p1) ) );
}
// a special bind version; mostly syntactic sugar
// note you can also deduce the first template parameter; would be more work
// and not necessary here
template < typename P1, typename F1, typename F2 >
auto bind_chain(F1 f1, F2 f2)
-> decltype( std::bind( &chain2<F1,F2,P1>, f1, f2, std::placeholders::_1 ) )
{
return std::bind( &chain2<F1,F2,P1>, f1, f2, std::placeholders::_1 );
}
// as `std::move` is overloaded, we make things a little bit simpler;
// we later will need to get a function pointer on this, that's why
// I'd like to avoid too much overloading
template < typename T >
// for a certain reason, cannot use && here --------v, clang++3.2 accepts it
typename std::remove_reference<T>::type && my_move(T& p)
{
return std::move(p);
}
struct wrapper
{
Object&& m;
wrapper(Object&& p) : m(std::move(p)) {}
operator Object&() const { return m; }
// alternatively:
// operator Object&&() const { return std::move(m); }
};
int main()
{
Object o;
// we'll need to call the functor with an const ref
function<void(wrapper const&)> i;
// chaining the conversion to rvalue ref with the target function
i = bind_chain<wrapper const&>( &f, &my_move<Object> );
i( move(o) );
return 0;
}

Resources