mirror of
https://github.com/qpdf/qpdf.git
synced 2024-06-03 19:00:51 +00:00
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>
|
2022-02-01 Jay Berkenbilt <ejb@ql.org>
|
||||||
|
|
||||||
* Major refactor: all functionality from the qpdf CLI is now
|
* Major refactor: all functionality from the qpdf CLI is now
|
||||||
|
|
|
@ -22,6 +22,14 @@
|
||||||
#ifndef POINTERHOLDER_HH
|
#ifndef POINTERHOLDER_HH
|
||||||
#define 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
|
// This class is basically std::shared_ptr but predates that by
|
||||||
// several years.
|
// several years.
|
||||||
|
|
||||||
|
@ -119,6 +127,12 @@ class PointerHolder
|
||||||
return this->data->pointer < rhs.data->pointer;
|
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
|
// NOTE: The pointer returned by getPointer turns into a pumpkin
|
||||||
// when the last PointerHolder that contains it disappears.
|
// when the last PointerHolder that contains it disappears.
|
||||||
T* getPointer()
|
T* getPointer()
|
||||||
|
@ -134,6 +148,12 @@ class PointerHolder
|
||||||
return this->data->refcount;
|
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
|
T const& operator*() const
|
||||||
{
|
{
|
||||||
return *this->data->pointer;
|
return *this->data->pointer;
|
||||||
|
|
|
@ -4,8 +4,6 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
#include <qpdf/QUtil.hh>
|
|
||||||
|
|
||||||
class Object
|
class Object
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -47,13 +45,20 @@ Object::hello() const
|
||||||
|
|
||||||
typedef PointerHolder<Object> ObjectHolder;
|
typedef PointerHolder<Object> ObjectHolder;
|
||||||
|
|
||||||
void callHello(ObjectHolder const& oh)
|
void callHello(ObjectHolder& oh)
|
||||||
{
|
{
|
||||||
oh.getPointer()->hello();
|
oh.getPointer()->hello();
|
||||||
oh->hello();
|
oh->hello();
|
||||||
(*oh).hello();
|
(*oh).hello();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void callHelloWithGet(ObjectHolder const& oh)
|
||||||
|
{
|
||||||
|
oh.get()->hello();
|
||||||
|
oh->hello();
|
||||||
|
(*oh).hello();
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
std::list<ObjectHolder> ol1;
|
std::list<ObjectHolder> ol1;
|
||||||
|
@ -66,7 +71,7 @@ int main(int argc, char* argv[])
|
||||||
std::cout << "oh1 refcount = " << oh1.getRefcount() << std::endl;
|
std::cout << "oh1 refcount = " << oh1.getRefcount() << std::endl;
|
||||||
ObjectHolder oh2(oh1);
|
ObjectHolder oh2(oh1);
|
||||||
std::cout << "oh1 refcount = " << oh1.getRefcount() << std::endl;
|
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 oh3(new Object);
|
||||||
ObjectHolder oh4;
|
ObjectHolder oh4;
|
||||||
ObjectHolder oh5;
|
ObjectHolder oh5;
|
||||||
|
@ -89,12 +94,15 @@ int main(int argc, char* argv[])
|
||||||
ol1.push_back(oh3);
|
ol1.push_back(oh3);
|
||||||
Object* o3 = new Object;
|
Object* o3 = new Object;
|
||||||
oh0 = o3;
|
oh0 = o3;
|
||||||
|
PointerHolder<Object const> oh6(new Object());
|
||||||
|
oh6->hello();
|
||||||
}
|
}
|
||||||
|
|
||||||
ol1.front().getPointer()->hello();
|
ol1.front().getPointer()->hello();
|
||||||
ol1.front()->hello();
|
ol1.front()->hello();
|
||||||
(*ol1.front()).hello();
|
(*ol1.front()).hello();
|
||||||
callHello(ol1.front());
|
callHello(ol1.front());
|
||||||
|
callHelloWithGet(ol1.front());
|
||||||
ol1.pop_front();
|
ol1.pop_front();
|
||||||
std::cout << "array" << std::endl;
|
std::cout << "array" << std::endl;
|
||||||
PointerHolder<Object> oarr1_ph(true, new Object[2]);
|
PointerHolder<Object> oarr1_ph(true, new Object[2]);
|
||||||
|
|
|
@ -10,17 +10,23 @@ destroyed Object, id 2
|
||||||
equal okay
|
equal okay
|
||||||
less than okay
|
less than okay
|
||||||
created Object, id 3
|
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 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
|
||||||
calling Object::hello const for 1
|
calling Object::hello const for 1
|
||||||
array
|
array
|
||||||
created Object, id 4
|
|
||||||
created Object, id 5
|
created Object, id 5
|
||||||
|
created Object, id 6
|
||||||
goodbye
|
goodbye
|
||||||
|
destroyed Object, id 6
|
||||||
destroyed Object, id 5
|
destroyed Object, id 5
|
||||||
destroyed Object, id 4
|
|
||||||
destroyed Object, id 3
|
destroyed Object, id 3
|
||||||
destroyed Object, id 1
|
destroyed Object, id 1
|
||||||
|
|
Loading…
Reference in New Issue
Block a user