Enabling swig::from when needed by custom templated types

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Enabling swig::from when needed by custom templated types

Jake
I'm trying to wrap some code which includes a custom vector type, let's call it MyVector, 
that is more or less like std::array (templated on size and element type) with a bunch of 
additional operations.  It doesn't conform to the sequence format that would let, e.g. 
traits_from_stdseq in pycontainer.swg to apply (I also don't know how I would make it 
apply if it did), but I took some inspiration from there and tried to write a macro:

%define %MyVector_sequence(size, type)
#ifdef SWIGPYTHON
%typemap(out) MyVector<size, type> {
  PyObject *obj = PyTuple_New((Py_ssize_t)size);
  for (decltype(size) i = 0; i < size; ++i) {
    PyTuple_SetItem(obj, i, swig::from<type>($1[i]));
  }
  $result = obj;
}
#endif
%enddef


With a use such as:

%template(MyVector2c)  MyVector<2, char>;
%MyVector_sequence(2, char);


This produces the error:

'type_name' : is not a member of 'swig::traits<char>'

Now, if this appears elsewhere in a used .i file:

%include "std_vector.i"

namespace std {
  %template(CharVector) vector<char>;
}

Then the traits< char >, traits_asval< char > and traits_from< char > specializations
are generated and swig::from<char> compiles.

So, my main question is what causes this registration and how would I trigger it?  
Secondarily, I wonder if it can be triggered automatically based on the template 
instantiation without using an extra macro for each?  Is it possible to do this 
without modifying the original C++ header or repeating its information?

-Jake Cobb

------------------------------------------------------------------------------
What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic
patterns at an interface-level. Reveals which users, apps, and protocols are
consuming the most bandwidth. Provides multi-vendor support for NetFlow,
J-Flow, sFlow and other flows. Make informed decisions using capacity planning
reports. http://pubads.g.doubleclick.net/gampad/clk?id=1444514421&iu=/41014381
_______________________________________________
Swig-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/swig-user
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Enabling swig::from when needed by custom templated types

Jake
In case it helps someone else, it seems the magic is in this fragment
definition:

    %fragment(SWIG_Traits_frag(SimpleVector), "header",
        fragment=SWIG_Traits_frag(double)) {
      namespace swig {
        template <>
        struct traits<SimpleVector> {
          typedef value_category category;
          static const char* type_name() {
            return "SimpleVector";
          }
        };
      }
    }

    %typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, SimpleVector);

Here SimpleVector is non-templated class using a fixed size and type, hence
double being used directly.  If this appears in the class definition
then the code
that enables swig::from<double> is generated.

Although SWIG's own code for std::vector and std::array includes it, I
can't see that
%traits_swigtype(double) does anything here and it can be left out
entirely to still get
the swig::from<double> support.  The other parts appear to be required.

-Jake

On Wed, Jun 15, 2016 at 12:52 PM, Jake <[hidden email]> wrote:

>
> I'm trying to wrap some code which includes a custom vector type, let's call it MyVector,
> that is more or less like std::array (templated on size and element type) with a bunch of
> additional operations.  It doesn't conform to the sequence format that would let, e.g.
> traits_from_stdseq in pycontainer.swg to apply (I also don't know how I would make it
> apply if it did), but I took some inspiration from there and tried to write a macro:
>
> %define %MyVector_sequence(size, type)
> #ifdef SWIGPYTHON
> %typemap(out) MyVector<size, type> {
>   PyObject *obj = PyTuple_New((Py_ssize_t)size);
>   for (decltype(size) i = 0; i < size; ++i) {
>     PyTuple_SetItem(obj, i, swig::from<type>($1[i]));
>   }
>   $result = obj;
> }
> #endif
> %enddef
>
> With a use such as:
>
> %template(MyVector2c)  MyVector<2, char>;
> %MyVector_sequence(2, char);
>
> This produces the error:
>
> 'type_name' : is not a member of 'swig::traits<char>'
>
> Now, if this appears elsewhere in a used .i file:
>
> %include "std_vector.i"
>
> namespace std {
>   %template(CharVector) vector<char>;
> }
>
> Then the traits< char >, traits_asval< char > and traits_from< char > specializations
> are generated and swig::from<char> compiles.
>
> So, my main question is what causes this registration and how would I trigger it?
> Secondarily, I wonder if it can be triggered automatically based on the template
> instantiation without using an extra macro for each?  Is it possible to do this
> without modifying the original C++ header or repeating its information?
>
> -Jake Cobb

------------------------------------------------------------------------------
What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic
patterns at an interface-level. Reveals which users, apps, and protocols are
consuming the most bandwidth. Provides multi-vendor support for NetFlow,
J-Flow, sFlow and other flows. Make informed decisions using capacity planning
reports.http://sdm.link/zohodev2dev
_______________________________________________
Swig-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/swig-user
Loading...