Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use SWIG to wrap a C++ operator[] in a template class inside a namespace?

I'm using SWIG to wrap an existing C++ library using just its header files. This library uses a namespace and a template class to create Arrays of custom objects. I'm running into problems trying to wrap the subscript operator (operator[]) used to access elements inside the wrapped arrays. SWIG tells me that operator[] is ignored and that I should use %extend instead:

small.i:18: Warning 389: operator[] ignored (consider using %extend)

So I'm trying to use extend but no matter what syntax I've tried, I can't get the inserted code to show up in the _wrap.cxx file. Here's my SWIG input file:

%module tltest
%{
...
%}

namespace nite {
    template <class T> class Array {
    public:
        %rename(__getitem__) operator[];
        const T& operator[](int index) const {return m_data[index];}

        %rename(__len__) getSize;
        int getSize() const {return m_size;}
    };

    class UserData : private NiteUserData
    {
    public:
    };

    %template(userDataArray) Array<UserData>;

};

%extend Array<UserData> {
    UserData& __getitem__(unsigned int i) {
        return $self[i];
     }
}

I know that I want to define the __getitem__ function for Python to be able to index into the array class. Note that the __len__ function does get renamed correctly, and works properly from the Python interface.

However, that %extend block that I added to define the __getitem__ call does not ever seem to get injected into the small_wrap.cxx wrapper file. Can anyone see what I'm doing wrong?

like image 467
Tessa Lau Avatar asked Oct 22 '22 10:10

Tessa Lau


1 Answers

Aha! I discovered that you need to qualify all types using the namespace in the %extend block, as follows:

%extend nite::Array<nite::UserData> {
    nite::UserData __getitem__(unsigned int i) {
        return (*($self))[i];
    }
}
like image 174
Tessa Lau Avatar answered Nov 01 '22 15:11

Tessa Lau