Re: %factory and templates

William S Fulton <[email protected]>
Newsgroups gmane.comp.programming.swig
Message-ID <CANGqftBHKznwq-69Si=vr6un7ZzGxHbG-tG5Zd+xaLpTsd55MA@mail.gmail.com>
On Sun, 18 Oct 2020 at 00:58, <[email protected]> wrote:

> *From:* kris.f.thielemans
> *Sent:* 10 October 2020 00:23
>
>
>
> *From:* William S Fulton <[email protected]>
> *Sent:* 09 October 2020 19:03
>
>
>
> On Fri, 9 Oct 2020 at 16:42, <kris.f.thielemans > wrote:
>
> Hi
>
>
>
> We are trying to use %factory (see
> https://github.com/swig/swig/blob/master/Lib/typemaps/factory.swg) to let
> SWIG do automatic downcasting to the actual types, as opposed to just
> returning the base class. However, at present it isn’t working for us. Our
> hunch is that this is due to templates and typemaps (which I don’t
> understand well enough). We haven’t boiled it down to a simple example yet,
> but I thought maybe would know the answer straight-away 😊
>
>
>
> We have a hierarchy like this (apologies for long names, but I kept the
> ones in our actual code)
>
>
>
> stir::GeneralisedPrior<TargetT >
>
> stir::QuadraticPrior<elemT> : public
> stir::GeneralisedPrior<DiscretisedDensity<3,elemT> >
>
> stir::RelativeDifferencePrior<elemT> : public
> stir::GeneralisedPrior<DiscretisedDensity<3,elemT> >
>
>
>
> (cutting out some intermediate classes)
>
>
>
> We then have some other templated class that has a member
>
>
>
> stir::GeneralisedPrior<TargetT >
> *GeneralisedObjectiveFunction<TargetT>::get_prior_ptr()
>
>
>
> So, in our SWIG interface file we say
>
>
>
> %newobject *::get_prior_ptr;
>
> %factory(stir::GeneralisedPrior
> *stir::GeneralisedObjectiveFunction::get_prior_ptr, stir::QuadraticPrior,
> stir::PLSPrior, stir::RelativeDifferencePrior);
>
>
>
> i.e. without any template stuff at all, but it seems that the typemap
> generated by %factory isn’t picked up.
>
>
>
> Anyone any suggestions?
>
>
>
>
>
>
>
> You need to instantiate your templates with %template if you aren't
> already.
>
>
>
> William
>
>
>
> Thanks William,
>
>
>
> Sorry to have posted incomplete code, but it is rather long due to the
> somewhat complicated hierarchy. We can try to make a reduced example. The
> %templates are there. Indeed, all the classes are callable from Python. It
> is just that the “factory” (get_prior_ptr) still returns a base object (GeneralisedPrior),
> as opposed to one of the leaf classes (QuadraticPrior etc).
>
>
>
> Relevant bits of our interface file are:
>
> -        %newobject, %factor, %include at
> https://github.com/UCL/STIR/blob/9c72b9ee8d584f4fd5729f496b7927fec8f55e4e/src/swig/stir.i#L1582-L1595
>
> -        %template stuff at
> https://github.com/UCL/STIR/blob/9c72b9ee8d584f4fd5729f496b7927fec8f55e4e/src/swig/stir.i#L1634-L1650
>
>
>
> I’m not sure how to debug the typemap question but will have a look at the
> debug switches of SWIG, unless there are any easier suggestions.
>
>
>
>
>
> After including factory.i (sorry!), it does work if I add *complete
> template specifications*, as in
>
>
>
> %factory(stir::GeneralisedPrior<TargetT>
> *stir::GeneralisedObjectiveFunction< TargetT >::get_prior_ptr,
>
>          stir::QuadraticPrior<elemT>,
>
>          stir::PLSPrior<elemT>,
>
>          stir::RelativeDifferencePrior<elemT>);
>
>
>
> where I have a %define for TargetT and elemT. I suppose I would have to
> repeat this for every instantiation that I want. (Indeed, it seems unlikely
> that SWIG can figure this out if I don’t specify the template arguments, as
> it wouldn’t know what to insert in the wrapper code).
>
>
>
> Great!
>
>
>
> However, now I stumble on another problem. In our actual code, the derived
> class can itself be a *template with 2 or more arguments*, e.g. in a
> simple example
>
>
>
> %factory(Base* Base::create, mytemplate<int,int>);
>
>
>
> When running SWIG, I get an error
>
>
>
> Error: Bad $descriptor() macro.
>
>
>
> I presume this is because of the comma. So I tried William’s trick he told
> me once about: use %arg(). As in
>
>
>
> %factory(Base* Base::create, %arg(mytemplate<int,int>));
>
>
>
> But that didn’t help either. Conceivably this could be because the factory
> macro would itself have to use %arg somehow, e.g. here
>
>
> https://github.com/swig/swig/blob/b6c2438d7d7aac5711376a106a156200b7ff1056/Lib/typemaps/factory.swg#L84
>
> but I have no idea really.
>

Look at the preprocessor output after the macro expansions using swig -E.
Quite possibly the %factory macros need some extra %arg usage. There is far
too much weird macro hackery in %factory, I would just write it out long
hand if it doesn't work or put aside some considerable time to debug these
non-standard macros!

William


William

_______________________________________________
Swig-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/swig-user
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.