ArafatK ArafatK - 5 months ago 23
Ruby Question

Convert std::set to ruby with Swig

I am using Swig to use C++ in ruby and Currently I have done a simple example of file david.h

#include <stdio.h>
class David
{
public:
David(int x)
{
this->x = x;
}
void announce()
{
printf("David %d\n", x);
}
int x;
};


And another file for swig like this

%module "david"
%{
#include <libdavid.h>
%}
class David
{
public:
David(int x);
void announce();
int x;
};


My
extconf.rb
looks like this

require 'mkmf'
system('swig -c++ -ruby libdavid.i') or abort
create_makefile('david')


This helps me perform an extremely simple example in ruby like this

2.2.1 :001 > a=David::David.new(42)
=> #<David::David:0x000000022c3ec0 @__swigtype__="_p_David">
2.2.1 :002 > a.x
=> 42


Now I have been trying very hard for a while now but I simply can't figure out how to use set from c++ stl as given in example here.
It would be really nice if someone could help me out with how I could create a stl set of integers or maybe vector and show how to insert and erase methods work on that set/vector. Simple code samples would be very useful not just for me but for many people who could face this in future.




This just a personal request feel free to skip this if you are busy.

To be honest I have been using stack overflow for quite a while now but slowly I am starting to get disappointed with the community. I have been posting a few questions and I have not received satisfactory answers, No up-votes, no Down-votes, nothing, I just don't receive any answers. What surprises me is that extremely trivial questions that can be answered in a simple google search are often very popular, and important questions from new users are either heavily down voted or totally ignored. I understand that the community does not OWE me anything. But I would be very thankful if someone could explain the possible reasons for that.

Thanks

Answer

This is not complete but could serve as a useful reference. I could not find a proper documentation for this but it works fine. Add this to swig file

%include <std_set.i>
namespace std {
   %template(IntSet) set<int>;
}

Now run the extconf.rb And now the following commands for set are supported in ruby

2.2.1 :001 > a=David::IntSet.new
 => std::set<int,std::less< int >,std::allocator< int > > [] 
2.2.1 :002 > a.push(4)
 => 4 
2.2.1 :003 > a.push(1)
 => 1 
2.2.1 :004 > a.push(123)
 => 123 
2.2.1 :005 > a.push(612)
 => 612 
2.2.1 :006 > a
 => std::set<int,std::less< int >,std::allocator< int > > [1,4,123,612] 
2.2.1 :007 > a[0]
 => 1 
2.2.1 :008 > a.erase(a.begin)
 => nil 
2.2.1 :009 > a
 => std::set<int,std::less< int >,std::allocator< int > > [4,123,612] 
2.2.1 :010 > a[0]
 => 4 
2.2.1 :011 > a[1]
 => 123 
2.2.1 :012 > a.erase(a.begin)
 => nil 
2.2.1 :013 > a
 => std::set<int,std::less< int >,std::allocator< int > > [123,612] 

How push works like insert for set is still not clear to me but it works. But this example clearly shows how set can be used. A similar approach can be used for vector.

This answer is certainly not complete and answers/comments from experienced users are most welcome.

Comments