Looks good, except that your proposed qIntrusiveDetached() has (apparently) the same "uncertainty" that caused shared_ptr::unique() to be deprecated. https://en.cppreference.com/w/cpp/memory/shared_ptr/unique
Philippe On Wed, 07 Aug 2019 23:09:54 +0300 "Mutz, Marc via Development" <development@qt-project.org> wrote: > On 2019-08-07 22:01, Konstantin Tokarev wrote: > > It would be even better if it was possible to choose type of reference > > counting, > > e.g. via template parameter. In many cases atomic counters are not > > needed > > and just reduce performance. > > On 2019-08-07 21:46, Philippe wrote: > > On Wed, 07 Aug 2019 21:00:30 +0300 > > "Mutz, Marc" <m...@kdab.com> wrote: > [...] > >>> I think I'm on record saying such impl details as ref-counting for Qt > >>> implicitly shared classes > >>> should not be public API. This is a perfect example of why I believe > >>> that to be fundamentally true. > > > > +1 > > I have just uploaded my proposed solution for this: > QIntrusiveSharedPointer. Even though I didn't have a) taking Qt pimpl > private and b) allowing non-atomic ref counts use-cases in mind when I > designed it, it supports these use-cases out of the box. I think its > design will satisfy all the constraints, even though I'd like to see a > round of internal use first (5.14, or, more likely by now 5.15, make > public in Qt 6): > > - provide a public replacement for > QSharedDataPointer/QExplicitlySharedDataPointer with all their (known) > shortcomings fixed > > while at the same time: > > - allow Qt to use it's own private reference counting (by having > qshareddatav2_p.h and the Intrusive Protocol implemented like for > QSharedData); I haven't implemented a QSDV2, yet, but off the top of my > head the ref-counting is always out-of-line, so it's possible to > retrofit it into already-released classes > > - allow users to use a simple int as ref-count > > This is an evolution of > https://codereview.qt-project.org/c/qt/qtbase/+/115213 and it has all > the benefits of QtPrivate::SharedDataPointer to, to wit: > > - it's possible to have an inline move ctor: > > just need to export an out-of-line overload of > qIntrusiveDeref(QXXXPrivate*), which can call > qIntrusiveDeref<QXXXPrivate>() if Private is derived from a supported > QSharedData-alike > > - in the same way, even the dtor can be inline > - it's even possible to have all special member functions = default'ed > > by exporting qIntrusiveRef() in addition. This reduces the number of DLL > entry points from 4 (default, copy ctor/assignment op, dtor) to two > (qIntrusive(De)ref()). > > - const propagating > - explicit detach > - proper conversion to bool (unlike QSDP, which detaches, making every > if (mutable d) tautological) > > It also adds > > - constexpr default ctor and ctor from nullptr > - implicit ctor from nullptr (but explicit from T*) > > Which means that on conforming compilers (not MSVC) a static QISP > init'ed to nullptr will be placed into the BSS segment and not cause > dynamic initialisation (even if the dtor is not trivial - the std::mutex > principle). > > The only drawback over QtPrivate::SharedDataPointer is that you need to > manually declare and implement qIntrusiveRef() and qIntrusiveDeref(); we > can't hide it in (one) macro. But I think that's a benefit. It reduces > the number of DLL entry points over the static-Public-member-functions > design of QtP::SDP, which is probably the reason it consistently > produces less executable code than QSDP, QESDP and not more code than > QtP::SDP did (which sometimes, e.g. for QCommandLineArgument, increased > text size a bit). > > Flame away... > > Thanks, > Marc > _______________________________________________ > Development mailing list > Development@qt-project.org > https://lists.qt-project.org/listinfo/development _______________________________________________ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development