MappedType for unique_ptr
Julien Cabieces
julien.cabieces at oslandia.com
Thu Nov 21 08:35:55 GMT 2024
Hi,
> *sipCppPtr = new std::unique_ptr<TYPE>( t );
If I understand well, you try to use the copy constructor which is
deleted. I would rather write something like
(*sipCppPtr).reset( t );
Regards,
Julien
> On Wed, 20 Nov 2024 at 20:40, Phil Thompson <phil at riverbankcomputing.com> wrote:
>>
>> On 20/11/2024 04:57, Nyall Dawson wrote:
>> > Hi list,
>> >
>> > I'm wondering if any one has had any luck in creating a MappedType to
>> > handle unique_ptr objects.
>> >
>> > I've been experimenting with the following implementation, which seems
>> > to
>> > work well for converting from unique_ptrs to Python owned objects. But
>> > I
>> > can't find any way to implement the ConvertToTypeCode so that I can
>> > wrap
>> > functions which have unique_ptr arguments.
>> >
>> > I'm really hoping to modernize some API and move away from raw
>> > pointers,
>> > but this is a stumbling block...
>> >
>> > template <TYPE>
>> > %MappedType std::unique_ptr< TYPE >
>> > /NoRelease,AllowNone,TypeHint="Optional[TYPE]",TypeHintValue="TYPE"/
>> > {
>> > %TypeHeaderCode
>> > #include <memory>
>> > %End
>> >
>> > %ConvertFromTypeCode
>> > const sipTypeDef *sip_type = sipFindType("TYPE*");
>> > return sipConvertFromNewType(sipCpp->release(), sip_type, NULL);
>> > %End
>>
>> Obviously I don't know the detail of your use-case but you are
>> hard-coding a particular ownership protocol by using
>> sipConvertFromNewType() and release() rather than sipConvertFromType()
>> and get().
>
> What I'm attempting to do is modernize some c++ API which looks like this:
>
> SomeClass* createObject() { return new SomeClass(); }
> void setObject( SomeClass* object ) { // something which takes
> ownership of object }
>
> Currently this would be exposed using sip bindings:
>
> SomeClass* createObject() /Factory/;
> void setObject( SomeClass* object /Transfer/ );
>
> The modernized c++ API would be something like:
>
> std::unique_ptr< SomeClass > createObject() { return
> std::make_unique< SomeClass >(); }
> void setObject( std::unique_ptr< SomeClass > object ) { //
> something which takes ownership of the pointed to object }
>
>> Obviously I don't know the detail of your use-case but you are
>> hard-coding a particular ownership protocol by using
>> sipConvertFromNewType() and release() rather than sipConvertFromType()
>> and get().
>
> Here I can safely assume that .release() is correct, because we are
> ALWAYS transferring ownership to the Python caller.
>
>>
>> > %ConvertToTypeCode
>> > // only one way for now...
>> > return 0;
>> > %End
>> > };
>>
>> What's the problem with using the unique_ptr<> ctor?
>
> This is the closest I got:
>
> %ConvertToTypeCode
> const sipTypeDef *sip_type = sipFindType("TYPE");
>
> if (sipIsErr == NULL)
> {
> if (!sipCanConvertToType(sipPy, sip_type, 0))
> return 0;
> return 1;
> }
>
> if (sipPy == Py_None)
> {
> *sipCppPtr = new std::unique_ptr<TYPE>();
> return 1;
> }
> else
> {
> int state;
> TYPE *t = reinterpret_cast<TYPE *>(sipConvertToType(sipPy,
> sip_type, sipTransferObj, 0, &state, sipIsErr));
> sipReleaseType(t, sip_type, state);
> if (*sipIsErr)
> {
> return 0;
> }
> *sipCppPtr = new std::unique_ptr<TYPE>( t );
> return sipGetState(sipTransferObj);
> }
> %End
>
> However, it fails to build when used with the "void setObject(
> std::unique_ptr< SomeClass > object );" function. I get a compilation
> error:
>
> In function ‘PyObject* meth_MyClass_setObject(PyObject*, PyObject*, PyObject*)’:
> error: use of deleted function ‘std::unique_ptr<_Tp,
> _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp =
> SomeClass; _Dp = std::default_delete<SomeClass>]’
>
> Thanks,
> Nyall
--
Julien Cabieces
Senior Developer at Oslandia
julien.cabieces at oslandia.com
More information about the PyQt
mailing list