How to store CPP classe in R object? - c++

I want to know if there is a way to store a CPP class in a R object.
I understand that we can call CPP function in R and we can also call method of a CPP class.
But I want to manipulate the CPP class in a R object, I don't know if this is possible.
Example :
I call this code in a R Script :
dyn.load(paste("X", .Platform$dynlib.ext, sep = ""))
.C("X_main")
The function X_main :
extern "C" {
void X_main () {
X x;
}
}
in X.cpp :
X::X() { cout<<"constructor X\n"<<endl;}
Can I store an object of the class "X" in a R object ? And use method of class "X" on the object stored (after in the script) ?
Or, Can I store in the memory an object of the class X ? I want to use this object several times.

By writing converters, you can assign the components of X which map to types R also knows: integer, numeric, character, ... all as scalar or vector, and of course composites of these.
But you do not get it for free. With Rcpp and friends, we have all the wrapper -- as well as a bunch of build tools -- to make this easy:
R> library(Rcpp)
R> cppFunction("arma::mat doubleIt(arma::mat X) { return 2*X; }",
+ depends="RcppArmadillo")
R> doubleIt(matrix(1:9,3))
[,1] [,2] [,3]
[1,] 2 8 14
[2,] 4 10 16
[3,] 6 12 18
R>
There are over 900 other Rcpp questions here, almost 100 worked examples at the Rcpp Gallery site. Have a look around!

You can load a C++ class (and probably struct) within R, which saves variables within class scope. R treats C++ classed like an S4 class.
Under the hood, a pointer to a C++ object instance is passed around, so you can create an object instance in C++ and then pass it to R sharing data.
To learn how to do this, it's about 7 pages, but well worth the read, so get out a cup of coffee and checkout: Exposing C++ functions and classes with Rcpp modules by Dirk Eddelbuettel and Romain François.
An example from the pdf:
class Bar {
public:
Bar(double x_) : x(x_), nread(0), nwrite(0) {}
double get_x() {
nread++;
return x;
}
void set_x(double x_) {
nwrite++;
x = x_;
}
IntegerVector stats() const {
return IntegerVector::create(_["read"] = nread,
_["write"] = nwrite);
}
private:
double x;
int nread, nwrite;
};
RCPP_MODULE(mod_bar) {
class_<Bar>( "Bar" )
.constructor<double>()
.property( "x", &Bar::get_x, &Bar::set_x )
.method( "stats", &Bar::stats )
;
}
And in R:
Bar <- mod_bar$Bar
b <- new(Bar, 10)
b$x + b$x
b$stats()
b$x <- 10
b$stats()

Related

C++ Automatically Exposing Class Members to Multiple APIs

Short:
There are many clever libraries out there that allow you to expose a class' members for various purposes, such as serialisation, exposure to a lua environment, etc. The problem is that for each clever solution you have to register a class' stuff for each api, which results in a lot of work duplication and boilerplate.
What is a way that I can register a class and its members and methods ONCE with some kind of flags attached and get various autogenerated methods
Long:
Lets say I have a class:
class C {
public:
int i; // Some int
vec3 v; // Some non-POD value
int function(int foo, char bar) // Some function
int hidden; // Some internal stuff I don't want exposed
}
What I'd like to do is be able to mark various members and methods at declaration time to have them be put in the various boilerplate automatically:
So declaration might look like:
class C {
public:
LUAREG JSON BINSER int i; // Marks member "i" to be exposed to the lua enviroment,
// JSON serialisable, binary serialisable
JSON vec3 v; // Only exposed to JSON function
LUAREG void someFunction() {} // Marks this method to be exposed to the lua enviroment
}
Or perhaps writing one registration function that does all the declarations:
void C::register_class() {
registrator::register_class<C>("C")
.addData("i", &i, FLAG_LUA | FLAG_JSON | FLAG_BINARY_SERIALISABLE)
.addFunction("someFunction", &someFunction, FLAG_LUA)
.end_class()
}
(I've seen this pattern some times - does this have a name?)
I want to be able to automatically generate various boilerplate functions for said class. For example:
/// Adds all fields with FLAG_JSON to a "json" object to be later serialised
void toJson(const C & c, json & j) {
toJson(c.i, "i", j);
toJson(c.v, "v", j);
}
/// Binary seralises all members with flag FLAG_BINARY_SERIALISABLE and stores the result in s
void serialise(const C & c, string & s) {
serialise(c.i, s);
serialise(c.v, s);
}
/// Registers all stuff with flag FLAG_LUA to some lua environment
void register_lua(lua_State * const L) {
luaReg_FetchContext(L)::addClass("C")
.addData("x", &C::x).comment("Some int") // generates documentation of "int x : Some int"
.addData("v", &C::v).comment("Some vector")
.addFunction("function", &C::function).comment("some function") // generates: "int function(int, char) : some function"
.endClass()
}
/// Register to some *other* lua environment (such as a read only context for rendering)
void register_lua_readonly(lua_State * const L2) {
luaReg_FetchContext(L)::addClass("C")
.addData("x", &C::x, false).comment("Some int")
.endClass()
}
/// Generates some user readable breakdown of all members
string dump() {
...
}
Now you can see with many classes this will become very tedious, bloaty and error prone to do manually
What is the best way to approach this? I am tempted to use a macro to spit out the functions, but have no idea how to approach the registration stage. Cheers!
I have a solution for this - I rolled my own reflection library - https://github.com/SnapperTT/STTR
class C {
public:
int i;
double d;
int func(int z) const {
return z;
}
static int static_var;
static int static_func() { return 5; }
};
int C::static_var = 7;
struct D : public C {
int di;
};
int main(int argc, char ** argv) {
// Registration
sttr::RegNamespace mNamespace("testns");
mNamespace.beginClass<C>("C")
.regField(&C::i, "i")
.regField(&C::d, "d")
.setUserFlags(0x00F00BAA) // Sets the user flags for the last added item
.setUserString("You can use this for whatever")
.setUserData((void *) &someStruct)
.regField(&C::func, "func")
.regField(&C::static_var, "static_var")
.regField(&C::static_func, "static_func")
.endClass()
.findClass("C").beginClass<D>("D") // Class inherritance. Also you can just beginClass<D>("D") inside C
.regField(&D::di, "di")
.endClass();
}
The key to this solution is that I can attach flags to registered members (so LUA could be 1 << 0, JSON could be 1 << 1, etc.
Automatic json serialisation and lua registration is done via a visitor. The visitor checks if the members have the relevent flag and either does its thing or skips onto the next member.
I have also attempted to use RTTR: https://github.com/rttrorg/rttr - its a nice, if albeit bulky library. I rolled my own library because I didn't like the visitor interface and the voluminous template error messages.
Finally automatic documentation is done by running a script that does a bunch of regex find-and-substitutes to pick out cases of typename Foo; /// Some documentation and create a static const char * const docv_Foo = "Some documentation"; and registers it. This does add an intermediate step to compilation but its not at all bad.

Maintainability issue of refactoring "fA()" and "fB()" to "fAB(){return report;}"

When my program is very young, there are usually many functions that do simple things.
When it became older, I found that it is more convenient to bundle some similar functions together, and group the return results of old functions as a "Report".
The "Report" can be easily passed around as a communication package among different modules.
Example 1
Code V1
class B{
float getWidth(C c){
float width= ... (very cheap function about "c") ;
return width;
}
float getHeight(C c){
float height= ... (very cheap function about "c") ;
return height;
}
};
Code V2
class ReportSize { float width; float height; }
class B{
ReportSize getSize(C c){ //<-- grouped
float width = ... ;
float height= ... ;
return ReportSize(width ,height);
}
};
Example 2
Code V1
class D{
Vector3 calculateNarrow(){ ... }
Vector3 calculateBoard(){ ... }
};
Code V2
class ReportVector3Pair{
Vector3 resultNarrow;
Vector3 resultBoard;
Vector3 get(NARROW_OR_BOARD paramEnum){
//return "resultNarrow" or "resultBoard"
}
};
class D{
ReportVector3Pair calculate(){ ... } //<-- grouped
};
Question
The refactoring cost some development time. All locations of code (up to 100 callers) have to be manually refactored to match the new signature.
How to minimize the chance of the need to refactor it later? How to minimize cost of the refactoring if it may happen in future?
How to minimize the chance of the need to refactor it later?
Create non-member functions that can return higher level objects instead of changing existing classes.
For example, instead of writing V2 of B, keep the existing B and use:
class ReportSize { float width; float height; }
ReportSize getReportSize(B const& b, C c)
{
return {b.getWidth(c), b.getHeight(c)}
}
Similarly, instead of creating V2 of D, keep existing D and use:
Vector3 calculate(D const& d, NARROW_OR_BOARD paramEnum) {
//return "resultNarrow" or "resultBoard"
}
How to minimize cost of the refactoring if it may happen in future?
Use non-member functions to extend functionality instead of modifying existing classes.
According to Scott Meyers, using non-member functions improves encapsulation.
Using non-member functions to add new functionality also follows The Open/Closed Principle.

Rcpp return of C/C++ Array Pointer Object

i want to write my own Datatype in C/C++.
I generated a small class like this :
#include <Rcpp.h>
using namespace Rcpp;
class Test
{
public:
int rows;
int cols;
float a[10];
Test() {};
};
RCPP_EXPOSED_CLASS( Test )
RCPP_MODULE(mod){
class_<Test>("Test")
.constructor()
.field("rows", & Test::rows )
.field("rows", & Test::cols )
// .field("a", & Test :: a)
;
}
the code is running. But now i want to get the values from a. Ive i understand the documentation correct i have to create a "as" function ? And return a NumericVector ?
I didnt understand the SEXP type, is it a pointer that is "typeless" and can be used in C/c++ and R ?
That's a lot of somewhat elementary questions.
Maybe you should not start with a module and class? How about
You could rewrite your class containing a std::vector<double> a.
You write a simple 'init()' function that assigns the class to file-local variable (usually a pointer).
You write little setter and getter functions, see Rcpp Attributes.
Once a few things are more clear more doing basics, revisit the Rcpp Modules vignette.

Boost::Python- possible to automatically convert from dict --> std::map?

I've got a C++ class, with a member function that can take a small-to-large number of parameters. Lets name those parameters, a-f. All parameters have default values. As a part of the python project I am working on, I want to expose this class to python. Currently, the member function looks something like this:
class myClass {
public:
// Constructors - set a-f to default values.
void SetParameters(std::map<std::string, double> &);
private:
double a, b, c, d, e, f;
}
void myClass::SetParameters(std::map<std::string, double> const& params) {
// Code to iterate over the map, and set any found key/value pairs to their
// corresponding variable. i.e.- "a" --> 2.0, would set myClass::a to 2.0
}
Ideally, in Python, I would like to accomplish this using a dict:
>>> A = myModule.myClass();
>>> A.SetParameters({'a': 2.2, 'd': 4.3, b: '9.3'})
In this way, the user could enter the values in any order, and enter any number of them to be over-ridden. Any thoughts on how this could be accomplished in boost::python? It seems to me that I can do this via changing the map input to a boost::python object, and using the extract functions. However, this would require me to change the interface of my library (I'd prefer to keep the std::map interface, and have some intermediary/auto conversion technique for the python version). Thoughts?
I think there's a couple of ways that are easier to accomplish than writing your own converter. You can use boost::python's map_indexing_suite to do the conversion for you, or you can use keyword arguments in python. I personally prefer keyword arguments, as this is the more "Pythonic" way to do this.
So this is your class (I added a typedef for the map):
typedef std::map<std::string, double> MyMap;
class myClass {
public:
// Constructors - set a-f to default values.
void SetParameters(MyMap &);
private:
double a, b, c, d, e, f;
};
Example using map_indexing_suite:
#include <boost/python/suite/indexing/map_indexing_suite.hpp>
using boost::python;
BOOST_PYTHON_MODULE(mymodule)
{
class_<std::map<std::string, double> >("MyMap")
.def(map_indexing_suite<std::map<std::wstring, double> >() );
class_<myClass>("myClass")
.def("SetParameters", &myClass::SetParameters);
}
Example using keyword arguments. This requires using a raw_function wrapper:
using namespace boost::python;
object SetParameters(tuple args, dict kwargs)
{
myClass& self = extract<myClass&>(args[0]);
list keys = kwargs.keys();
MyMap outMap;
for(int i = 0; i < len(keys); ++i) {
object curArg = kwargs[keys[i]];
if(curArg) {
outMap[extract<std::string>(keys[i])] = extract<double>(kwargs[keys[i]]);
}
}
self.SetParameters(outMap);
return object();
}
BOOST_PYTHON_MODULE(mymodule)
{
class_<myClass>("myClass")
.def("SetParameters", raw_function(&SetParameters, 1));
}
this allows you to write stuff like this in Python:
A.SetParameters(a = 2.2, d = 4.3, b = 9.3)
This blog post has a pretty clear description of how to write these converters. The basic pattern is to define a class that has the form:
struct SomeType_from_PyObject
{
SomeType_from_PyObject();
static void* convertible(PyObject* obj_ptr);
static void construct(PyObject* obj_ptr,
converter::rvalue_from_python_stage1_data* data);
};
Where the constructor is responsible for adding this converter to Boost.Python's registry:
SomeType_from_PyObject::SomeType_from_PyObject()
{
converter::registry::push_back(&convertible,
&construct,
type_id<SomeType>());
}
The function convertible tells Boost whether or not this converter can convert the specified Python object:
void* SomeType_from_PyObject::convertible(PyObject* obj_ptr)
{
if (PyMapping_Check(obj_ptr)) {
return obj_ptr;
} else {
return NULL;
}
}
The construct function actually creates an object of the conversion type:
void SomeType_from_PyObject::construct(PyObject* obj_ptr,
converter::rvalue_from_python_stage1_data* data)
{
typedef converter::rvalue_from_python_storage<SomeType> storage_t;
storage_t* the_storage = reinterpret_cast<storage_t*>(data);
void* memory_chunk = the_storage->storage.bytes;
object obj(handle<>(borrowed(obj_ptr)));
SomeType* output = new (memory_chunk) SomeType();
// Use the contents of obj to populate output, e.g. using extract<>
data->convertible = memory_chunk;
}
and then in your inside your BOOST_PYTHON_MODULE, include the line
SomeType_from_PyObject();
I'm just getting my toes wet with boost::python so can't completely answer your question. But the first roadblock I see is guaranteeing that the py dict's keys are all strings. Python dicts can also be keyed on tuples (and I assume more types).

How to eliminate a copy of variable in base class with multiple inheritance?

As title describes, I have 3 classes:
#include <iostream>
using namespace std;
class first
{
protected :
int data;
public :
first()
:data( 1 )
{
// empty
}
};
class second : public first
{
protected :
double x;
public :
second()
:first()
{
// empty
}
};
class combine : public first, public second
{
public :
combine()
{
// empty
}
};
int main()
{
combine c;
cout << sizeof( c ) << endl;
return 0;
}
When I check the sizeof( first ) is 4 which make sense to me. But I don't know why sizeof( second ) is 16 ( I assumed 4 + 8 = 12 != 16 ), and sizeof( combine ) is 24 ( 4 + 4 + 8 = 16 != 24 ). Could anyone help me to explain this?
Further, when 'combine' multiple inherits from 'first' and 'second', I realized that its size includes both data ( int ) from 'first' and 'second' class; which is a waste of memory. Is there any way to work around this issue, i.e. let 'first' and 'second' share one copy of 'data'?
This is what virtual inheritance is for. To keep first from being duplicated, everywhere you (directly) derive a class from first, you need to make the inheritance virtual, so you'd have:
class second : public virtual first { // ...
class combine : public virtual first, public second { // ...
Looks like the alignment is set to 8. This means that every sizeof above 8 is rounded up to a multiple of 8. Sizes below 8 are rounded to 8, 4, 2, or 1.
E.g.
First: int = 4.
Second: int + double = 4 + 8 = 12, round up to 16
Combine: int + second = 4 + 16 = 20, round up to 24.
And yes, the first::data is duplicated in combine. Use virtual inheritance (see other answers) to solve that. Or adjust your inheritance relations.
This is done in order to enhance memory access times at the cost of additional memory used.
If you can't spare the additional memory, look up the compiler magic to set the alignment to a lower value. Luckily, this is rarely needed.
If you really need this construction, you can use virtual inheritance:
http://www.parashift.com/c++-faq-lite/multiple-inheritance.html#faq-25.9