Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide typemaps for boost or std::optional<T> #1307

Open
nanan14 opened this issue Aug 15, 2018 · 13 comments
Open

Provide typemaps for boost or std::optional<T> #1307

nanan14 opened this issue Aug 15, 2018 · 13 comments
Assignees
Labels

Comments

@nanan14
Copy link

nanan14 commented Aug 15, 2018

Hi ,

is there a way to typemap boost::optional to c# int? and vice versa
and also for other type like bool , string and other classes?

so far I only found this implementation.
https://stackoverflow.com/questions/15912937/can-you-swig-a-boostoptional

%template(optionalInt) optional<int>;
%typemap(ctype) optional<int> "void *"; 
%typemap(imtype) optional<int> "global::System.IntPtr"; 
%typemap(cstype) optional<int> "int?"; 
%typemap(csin) optional<int> "$csinput";
%typemap(out) optional<int> %{
    std::vector<int> result_vec;
    if (!!$1)
    {
        result_vec = std::vector<int>(0, $1.get());
    }
    else
    {
        result_vec = std::vector<int>();
    }
    $result = new std::vector< int >((const std::vector< int > &)result_vec); 
%}
%typemap(csout, excode=SWIGEXCODE) boost::optional<int> {
     global::System.IntPtr cPtr =$imcall;$excode
	 if (cPtr != global::System.IntPtr.Zero)
	 {
	     return (int)($imcall);
	 }
	 return null;
}
%typemap(csvarout, excode=SWIGEXCODE) optional<int>
%{ 
    get 
    { 
         global::System.IntPtr cPtr =$imcall;$excode
	    if (cPtr != global::System.IntPtr.Zero)
	    {
	        return (int)($imcall);
	    }
	    return null;
    } 
%}
@vadz
Copy link
Member

vadz commented Aug 15, 2018

There are no standard typemaps for this in SWIG but I do have my own typemaps for std::optional-like class for C#, Java and Python (OK, so the latter one is trivial, but still). I could tidy them up for the inclusion in SWIG itself if there is sufficient interest.

@aksswami
Copy link

It would be great if you can share the snippet as I am also looking for the same. I am new to the SWIG and type mapping complex type is something I don’t understand as of now.

@wsfulton
Copy link
Member

@vadz, yes! They ought to port to std::optional which we ought to also have in SWIG.

@nanan14
Copy link
Author

nanan14 commented Aug 16, 2018

@vadz yes can you guide me in the right track.

@vadz vadz self-assigned this Aug 16, 2018
@vadz vadz changed the title typemapping c++ boost::optional<int> to C# int? Provide typemaps for boost or std::optional<T> Aug 16, 2018
@vadz vadz added the C++17 label Aug 16, 2018
@diegoferigo
Copy link

@vadz Is the std::optional support a feature you are still working on? Can you please provide the snippet you mentioned in the meantime?

@vadz
Copy link
Member

vadz commented Mar 4, 2019

No, sorry, other higher priority tasks took over and I was never able to work on this.

I've created some gists showing the typemaps we're using:

  1. Main file including language-specific typemaps definitions.
  2. C# typemaps (you may not need VBA-specific stuff)
  3. Java typemaps (requires Java 8)
  4. Python typemaps

These typemaps are for a very simple custom OptionalValue<> type, but should be straightforward to adapt for std::optional<>.

@diegoferigo
Copy link

diegoferigo commented Mar 18, 2019

Thanks a lot @vadz, your files have been very helpful. I am currently using a very simple swig configuration for std::optional using this optional.i. It requires to instantiate templates with something similar to the following:

%include "optional.i"
%template(Optional_i) std::optional<int>;

In your example I have't understood the logic behind DEFINE_OPTIONAL_CLASS and DEFINE_OPTIONAL_SIMPLE. Do you have to instantiate your templates with %template?


I tried to make something more complex, similar to a templated typemap in order to have a more idiomatic usage from python, but I couldn't make it work. For instance, I would like to directly map optional numeric types and strings to the target language. In python:

# Using the C++ signature
# std::optional<int> constructAndReturnOptional(const std::optional<int>&)

myint = mymodule.constructAndReturnOptional(42)
type(myint) # <class 'int'>

myint = mymodule.constructAndReturnOptional()
type(myint) # <class 'NoneType'>

I am pretty sure that it can be done using templated fragments together with $typemap(out,T) in language-specific typemaps, but I don't have enough experience with swig.

Does anyone have any example? I tried to understand how is done for std::vector but I didn't get it entirely.

@vadz
Copy link
Member

vadz commented Mar 18, 2019

In your example I have't understood the logic behind DEFINE_OPTIONAL_CLASS and DEFINE_OPTIONAL_SIMPLE.

In C# the representation of C++ optional<T> is either T? if it's a simple class or just T if it's a class. A single macro wouldn't be able to distinguish between these 2 cases (or, at least, I don't know how would it do it), so I've created 2 of them.

Do you have to instantiate your templates with %template?

No, the macros contain it.

For idiomatic usage, you really shouldn't be using Optional_i at all. Just use integers or None on the Python side.

@diegoferigo
Copy link

In C# the representation of C++ optional is either T? if it's a simple class or just T if it's a class. A single macro wouldn't be able to distinguish between these 2 cases (or, at least, I don't know how would it do it), so I've created 2 of them.

I'm not really familiar with C#, but I think I got your point.

For idiomatic usage, you really shouldn't be using Optional_i at all. Just use integers or None on the Python side.

I updated my comment above to reflect what I really meant. Now it should be more clear.

@JacobVarghese1992
Copy link

JacobVarghese1992 commented Jun 21, 2020

Hey @vadz , Sorry for a noob question. I'm looking at your java version. What exactly is OptionalValue in there. I get a Template 'OptionalValue' is undefined error. I just replaced it with optional and std::optional and get the same error, just with optional.

EDIT: That's your custom optional class nm.

@vadz
Copy link
Member

vadz commented Jun 21, 2020

OptionalValue is our custom type similar to boost::optional and std::optional, you should replace it with the type you actually use for your optional values.

@SmrtSmrtnik
Copy link

+1 for feature request, for what it's worth.
i have lots of c++ code with std::optional all over the place I've been tasked to SWIGify into Java, so definitely going to be looking at @vadz link and https://stackoverflow.com/questions/30272562/swig-wrap-boostoptional-in-java + the JNI spec as I've never done JNI before (and new to SWIG). Good times.

@lluisalemanypuig
Copy link

+1 for feature request. I am also very interested in seeing this implemented in SWIG.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

8 participants