Conversion of Python list to class that takes a vector in a constructor

Lluís Alemany Puig <[email protected]> Mon, 25 Oct 2021 14:30:12 +0200
Newsgroups gmane.comp.programming.swig
Message-ID <[email protected]>
Hello all,

I have a C++ class S which takes a std::vector<int> as only input 
parameter in one of its constructors. I can create an object of S 
normally from Python using its constructor passing to it a python list 
([1,2,3,...]). However, I can't call the function calculate_sum (which 
takes a const S&) when I pass to it a python list instead an object of 
type S. To be more precise, in the following python code, the 
print("3:", ...)

    import library
    print("1:", library.return_pair(10))
    d = library.D()
    d.v = 3
    print("2:", library.calculate_sum(d, library.S([1,2,3,4])))
    print("3:", library.calculate_sum(d, [1,2,3,4]))

fails with the expected error message:

    Traceback (most recent call last):
       File "test.py", line 6, in <module>
         print(library.calculate_sum(d, [1,2,3,4]))
       File "library.py", line 261, in calculate_sum
         return _library.calculate_sum(d, s)
    TypeError: in method 'calculate_sum', argument 2 of type 'S const &'

I'm trying to overcome this problem. That is, I would like python to 
create an object of type S given that it has a constructor with a vector 
(C++ code at the end). Can this be done? If so, how? I tried typemaps 
but I don't seem to be able to get them working for this.

Many thanks in advance.

Looking forward to hearing from you,

Lluís.

C++ code:

    #pragma once
    #include <vector>
    class D {
    public:
         int v;
    };

    class S {
    public:
         S() noexcept = default;
         S(const std::vector<int>& _v) noexcept : v(_v) {}
         int elemsum() const noexcept {
             int s = 0;
             for (int k : v) { s += k; }
             return s;
         }
    private:
         std::vector<int> v;
    };

    int calculate_sum(const D& d, const S& s) { return s.elemsum() + d.v; }
    std::pair<int, S> return_pair(int v) {
         S s(std::vector<int>(v,v));
         return {s.elemsum(), s};
    }

Interface file (.i):

    %module library

    %include stdint.i
    %include std_string.i
    %include std_pair.i
    %include std_vector.i

    %template(_list_int) std::vector<int>;

    %{
    #include <sstream>
    #include "library.hpp"
    %}

    %include library.hpp

    %extend S {
         std::string __repr__() const {
             std::ostringstream out;
             out << "I am a simple 'S'";
             return out.str();
         }
    }

    %template(_pair_int_S) std::pair<int, S>;

Makefile:

    _library.so: library.o
         g++ -shared -O3 -o _library.so library.o -L
    /usr/lib/x86_64-linux-gnu/ -lpython3.8
    library.o: library.cxx
         g++ -fPIC -std=c++17 -O3 -c library.cxx -I /usr/include/python3.8
    library.cxx: library.i library.hpp
         swig -Wall -debug-tmused -c++ -python -py3 -o library.cxx library.i
    clean:
         rm -f library.cxx
         rm -f library.py
         rm -f library.o
         rm -f _library.so

_______________________________________________
Swig-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/swig-user