mirror of https://github.com/qpdf/qpdf.git
PointerHolder: add get() and use_count() for forward compatibility
PointerHolder will be replaced with shared_ptr, so let people start moving.
This commit is contained in:
parent
f76191f0c2
commit
f727bc9443
17
ChangeLog
17
ChangeLog
|
@ -1,3 +1,20 @@
|
|||
2022-02-04 Jay Berkenbilt <ejb@ql.org>
|
||||
|
||||
* PointerHolder: add a get() method and a use_count() method for
|
||||
compatibility with std::shared_ptr. In qpdf 11, qpdf's APIs will
|
||||
switch to using std::shared_ptr instead of PointerHolder, though
|
||||
there will be a PointerHolder class with a backward-compatible
|
||||
API. To ease the transition, we are adding get() now with the same
|
||||
semantics as std::shared_ptr's get. Note that there is a
|
||||
difference in behavior: const PointerHolder has always behaved
|
||||
incorrectly. const PointerHolder objects only returned const
|
||||
pointers. This is wrong. If you want a const pointer, use
|
||||
PointerHolder<T const>. A const PointerHolder just shouldn't allow
|
||||
its pointer to be reassigned. The new get() method behaves
|
||||
correctly in that calling get() on a const PointerHolder to a
|
||||
non-const pointer returns a non-const pointer. This is the way
|
||||
regular pointers behave.
|
||||
|
||||
2022-02-01 Jay Berkenbilt <ejb@ql.org>
|
||||
|
||||
* Major refactor: all functionality from the qpdf CLI is now
|
||||
|
|
|
@ -22,6 +22,14 @@
|
|||
#ifndef POINTERHOLDER_HH
|
||||
#define POINTERHOLDER_HH
|
||||
|
||||
// In qpdf 11, PointerHolder will be derived from std::shared_ptr and
|
||||
// will also include a fix to incorrect semantics of const
|
||||
// PointerHolder objects. PointerHolder only allows a const
|
||||
// PointerHolder to return a const pointer. This is wrong. Use a
|
||||
// PointerHolder<const T> for that. A const PointerHolder should just
|
||||
// not allow you to change what it points to. This is consistent with
|
||||
// how regular pointers and standard library shared pointers work.
|
||||
|
||||
// This class is basically std::shared_ptr but predates that by
|
||||
// several years.
|
||||
|
||||
|
@ -119,6 +127,12 @@ class PointerHolder
|
|||
return this->data->pointer < rhs.data->pointer;
|
||||
}
|
||||
|
||||
// get() is for interface compatibility with std::shared_ptr
|
||||
T* get() const
|
||||
{
|
||||
return this->data->pointer;
|
||||
}
|
||||
|
||||
// NOTE: The pointer returned by getPointer turns into a pumpkin
|
||||
// when the last PointerHolder that contains it disappears.
|
||||
T* getPointer()
|
||||
|
@ -134,6 +148,12 @@ class PointerHolder
|
|||
return this->data->refcount;
|
||||
}
|
||||
|
||||
// use_count() is for compatibility with std::shared_ptr
|
||||
long use_count()
|
||||
{
|
||||
return static_cast<long>(this->data->refcount);
|
||||
}
|
||||
|
||||
T const& operator*() const
|
||||
{
|
||||
return *this->data->pointer;
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
#include <stdlib.h>
|
||||
#include <list>
|
||||
|
||||
#include <qpdf/QUtil.hh>
|
||||
|
||||
class Object
|
||||
{
|
||||
public:
|
||||
|
@ -47,13 +45,20 @@ Object::hello() const
|
|||
|
||||
typedef PointerHolder<Object> ObjectHolder;
|
||||
|
||||
void callHello(ObjectHolder const& oh)
|
||||
void callHello(ObjectHolder& oh)
|
||||
{
|
||||
oh.getPointer()->hello();
|
||||
oh->hello();
|
||||
(*oh).hello();
|
||||
}
|
||||
|
||||
void callHelloWithGet(ObjectHolder const& oh)
|
||||
{
|
||||
oh.get()->hello();
|
||||
oh->hello();
|
||||
(*oh).hello();
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
std::list<ObjectHolder> ol1;
|
||||
|
@ -66,7 +71,7 @@ int main(int argc, char* argv[])
|
|||
std::cout << "oh1 refcount = " << oh1.getRefcount() << std::endl;
|
||||
ObjectHolder oh2(oh1);
|
||||
std::cout << "oh1 refcount = " << oh1.getRefcount() << std::endl;
|
||||
std::cout << "oh2 refcount = " << oh2.getRefcount() << std::endl;
|
||||
std::cout << "oh2 refcount = " << oh2.use_count() << std::endl;
|
||||
ObjectHolder oh3(new Object);
|
||||
ObjectHolder oh4;
|
||||
ObjectHolder oh5;
|
||||
|
@ -89,12 +94,15 @@ int main(int argc, char* argv[])
|
|||
ol1.push_back(oh3);
|
||||
Object* o3 = new Object;
|
||||
oh0 = o3;
|
||||
PointerHolder<Object const> oh6(new Object());
|
||||
oh6->hello();
|
||||
}
|
||||
|
||||
ol1.front().getPointer()->hello();
|
||||
ol1.front()->hello();
|
||||
(*ol1.front()).hello();
|
||||
callHello(ol1.front());
|
||||
callHelloWithGet(ol1.front());
|
||||
ol1.pop_front();
|
||||
std::cout << "array" << std::endl;
|
||||
PointerHolder<Object> oarr1_ph(true, new Object[2]);
|
||||
|
|
|
@ -10,17 +10,23 @@ destroyed Object, id 2
|
|||
equal okay
|
||||
less than okay
|
||||
created Object, id 3
|
||||
created Object, id 4
|
||||
calling Object::hello const for 4
|
||||
destroyed Object, id 4
|
||||
calling Object::hello for 1
|
||||
calling Object::hello for 1
|
||||
calling Object::hello for 1
|
||||
calling Object::hello for 1
|
||||
calling Object::hello for 1
|
||||
calling Object::hello for 1
|
||||
calling Object::hello for 1
|
||||
calling Object::hello const for 1
|
||||
calling Object::hello const for 1
|
||||
calling Object::hello const for 1
|
||||
array
|
||||
created Object, id 4
|
||||
created Object, id 5
|
||||
created Object, id 6
|
||||
goodbye
|
||||
destroyed Object, id 6
|
||||
destroyed Object, id 5
|
||||
destroyed Object, id 4
|
||||
destroyed Object, id 3
|
||||
destroyed Object, id 1
|
||||
|
|
Loading…
Reference in New Issue