mirror of https://github.com/qpdf/qpdf.git
Update documentation for PointerHolder transition
This commit is contained in:
parent
ef2b84c6c3
commit
c7e877b88b
|
@ -160,11 +160,16 @@ CODING RULES
|
|||
it seems also for classes that are intended to be subclassed across
|
||||
the shared library boundary.
|
||||
|
||||
* Put private member variables in PointerHolder<Members> for all
|
||||
* Put private member variables in std::shared_ptr<Members> for all
|
||||
public classes. Remember to use QPDF_DLL on ~Members(). Exception:
|
||||
indirection through PointerHolder<Members> is expensive, so don't do
|
||||
it for classes that are copied a lot, like QPDFObjectHandle and
|
||||
QPDFObject.
|
||||
indirection through std::shared_ptr<Members> is expensive, so don't
|
||||
do it for classes that are copied a lot, like QPDFObjectHandle and
|
||||
QPDFObject. It may be possible to declare
|
||||
std::shared_ptr<Members> m_ph;
|
||||
Member* m;
|
||||
with m = m_ph.get(), and then indirect through m in
|
||||
performance-critical settings, though in 2022, std::shared_ptr is
|
||||
sufficiently performant that this may not be worth it.
|
||||
|
||||
* Traversal of objects is expensive. It's worth adding some complexity
|
||||
to avoid needless traversals of objects.
|
||||
|
|
104
TODO
104
TODO
|
@ -5,8 +5,7 @@ Next
|
|||
* At next release, hide release-qpdf-10.6.3.0cmake* versions at readthedocs
|
||||
|
||||
In order:
|
||||
* cmake
|
||||
* PointerHolder -> shared_ptr
|
||||
* cmake -- remaining steps
|
||||
* ABI including --json default is latest
|
||||
* json v2
|
||||
|
||||
|
@ -29,9 +28,6 @@ Misc
|
|||
--show-encryption could potentially retry with this option if the
|
||||
first time doesn't work. Then, with the file open, we can read the
|
||||
encryption dictionary normally.
|
||||
* Go through README-maintainer "CODING RULES" and update --
|
||||
PointerHolder and other changes will make some of the rules
|
||||
obsolete.
|
||||
* Have a warn in QPDF that passes its variable arguments onto QPDFExc
|
||||
so you don't have to do warn(QPDFExc(...))
|
||||
|
||||
|
@ -57,6 +53,7 @@ cmake
|
|||
QPDF_DLL are public because QPDF_DLL_LOCAL makes the other things
|
||||
private. See https://gcc.gnu.org/wiki/Visibility. Make sure this
|
||||
is documented.
|
||||
* Update "CODING RULES" in "README-maintainer" - search for QPDF_DLL
|
||||
* Nice to have:
|
||||
* Split qpdf.test into multiple tests
|
||||
* Rework tests so that nothing is written into the source directory.
|
||||
|
@ -500,103 +497,6 @@ Other notes:
|
|||
way that works for the qpdf/qpdf repository as well since they are
|
||||
very similar.
|
||||
|
||||
PointerHolder to std::shared_ptr
|
||||
================================
|
||||
|
||||
To perform update:
|
||||
|
||||
Cherry-pick pointerholder branch commit
|
||||
|
||||
Upgrade just the library. This is not necessary, but it's an added
|
||||
check that the compatibility code works since it will show that tests,
|
||||
examples, and CLI will work properly with the upgraded APIs, which
|
||||
provides some assurance that other people will have a smooth time with
|
||||
their code.
|
||||
|
||||
patrepl s/PointerHolder/std::shared_ptr/g {include,libqpdf}/qpdf/*.hh
|
||||
patrepl s/PointerHolder/std::shared_ptr/g libqpdf/*.cc
|
||||
patrepl s/make_pointer_holder/std::make_shared/g libqpdf/*.cc
|
||||
patrepl s/make_array_pointer_holder/QUtil::make_shared_array/g libqpdf/*.cc
|
||||
patrepl s,qpdf/std::shared_ptr,qpdf/PointerHolder, **/*.cc **/*.hh
|
||||
git restore include/qpdf/PointerHolder.hh
|
||||
cleanpatch
|
||||
|
||||
Increase to POINTERHOLDER_TRANSITION=3
|
||||
|
||||
make build_libqpdf -- no errors
|
||||
|
||||
Drop back to POINTERHOLDER_TRANSITION=2
|
||||
|
||||
make check -- everything passes
|
||||
|
||||
Then upgrade everything else. It would work to just start here.
|
||||
|
||||
Increase to POINTERHOLDER_TRANSITION=3
|
||||
|
||||
patrepl s/PointerHolder/std::shared_ptr/g **/*.cc **/*.hh
|
||||
patrepl s/make_pointer_holder/std::make_shared/g **/*.cc
|
||||
patrepl s/make_array_pointer_holder/QUtil::make_shared_array/g **/*.cc
|
||||
patrepl s,qpdf/std::shared_ptr,qpdf/PointerHolder, **/*.cc **/*.hh
|
||||
git restore include/qpdf/PointerHolder.hh
|
||||
git restore libtests/pointer_holder.cc
|
||||
cleanpatch
|
||||
|
||||
Remove all references to PointerHolder.hh from everything except
|
||||
public headers and pointer_holder.cc.
|
||||
|
||||
make check -- everything passes
|
||||
|
||||
Increase to POINTERHOLDER_TRANSITION=4
|
||||
|
||||
Do a clean build and make check -- everything passes
|
||||
|
||||
Final steps:
|
||||
|
||||
* Change to POINTERHOLDER_TRANSITION=4
|
||||
* Check code formatting
|
||||
* std::shared_ptr<Members> m can be replaced with
|
||||
std::shared_ptr<Members> m_ph and Members* m if performance is critical
|
||||
* Could try Members indirection with Members* for QPDFObjectHandle
|
||||
|
||||
When done:
|
||||
|
||||
* Update the smart-pointers section of the manual in design.rst
|
||||
* Update comments in PointerHolder.hh
|
||||
|
||||
PointerHolder in public API:
|
||||
|
||||
PointerHolder<Buffer> Pl_Buffer::getBufferSharedPointer();
|
||||
PointerHolder<Buffer> QPDFWriter::getBufferSharedPointer();
|
||||
QUtil::read_file_into_memory(
|
||||
char const*, PointerHolder<char>&, unsigned long&)
|
||||
QPDFObjectHandle::addContentTokenFilter(
|
||||
PointerHolder<QPDFObjectHandle::TokenFilter>)
|
||||
QPDFObjectHandle::addTokenFilter(
|
||||
PointerHolder<QPDFObjectHandle::TokenFilter>)
|
||||
QPDFObjectHandle::newStream(
|
||||
QPDF*, PointerHolder<Buffer>)
|
||||
QPDFObjectHandle::parse(
|
||||
PointerHolder<InputSource>, std::string const&,
|
||||
QPDFTokenizer&, bool&, QPDFObjectHandle::StringDecrypter*, QPDF*)
|
||||
QPDFObjectHandle::replaceStreamData(
|
||||
PointerHolder<Buffer>, QPDFObjectHandle const&,
|
||||
QPDFObjectHandle const&)
|
||||
QPDFObjectHandle::replaceStreamData(
|
||||
PointerHolder<QPDFObjectHandle::StreamDataProvider>,
|
||||
QPDFObjectHandle const&, QPDFObjectHandle const&)
|
||||
QPDFTokenizer::expectInlineImage(
|
||||
PointerHolder<InputSource>)
|
||||
QPDFTokenizer::readToken(
|
||||
PointerHolder<InputSource>, std::string const&,
|
||||
bool, unsigned long)
|
||||
QPDF::processInputSource(
|
||||
PointerHolder<InputSource>, char const*)
|
||||
QPDFWriter::registerProgressReporter(
|
||||
PointerHolder<QPDFWriter::ProgressReporter>)
|
||||
QPDFEFStreamObjectHelper::createEFStream(
|
||||
QPDF&, PointerHolder<Buffer>)
|
||||
QPDFPageObjectHelper::addContentTokenFilter(
|
||||
PointerHolder<QPDFObjectHandle::TokenFilter>)
|
||||
|
||||
ABI Changes
|
||||
===========
|
||||
|
|
|
@ -53,13 +53,11 @@ or not if this information is needed. All access to objects deals with
|
|||
this transparently. All memory management details are also handled by
|
||||
the library.
|
||||
|
||||
The ``PointerHolder`` object is used internally by the library to deal
|
||||
with memory management. This is basically a smart pointer object very
|
||||
similar in spirit to C++-11's ``std::shared_ptr`` object, but predating
|
||||
it by several years. This library also makes use of a technique for
|
||||
giving fine-grained access to methods in one class to other classes by
|
||||
using public subclasses with friends and only private members that in
|
||||
turn call private methods of the containing class. See
|
||||
Memory is managed mostly with ``std::shared_ptr`` object to minimize
|
||||
explicit memory handling. This library also makes use of a technique
|
||||
for giving fine-grained access to methods in one class to other
|
||||
classes by using public subclasses with friends and only private
|
||||
members that in turn call private methods of the containing class. See
|
||||
``QPDFObjectHandle::Factory`` as an example.
|
||||
|
||||
The top-level qpdf class is ``QPDF``. A ``QPDF`` object represents a PDF
|
||||
|
@ -68,13 +66,14 @@ files.
|
|||
|
||||
The primary class for interacting with PDF objects is
|
||||
``QPDFObjectHandle``. Instances of this class can be passed around by
|
||||
value, copied, stored in containers, etc. with very low overhead.
|
||||
Instances of ``QPDFObjectHandle`` created by reading from a file will
|
||||
always contain a reference back to the ``QPDF`` object from which they
|
||||
were created. A ``QPDFObjectHandle`` may be direct or indirect. If
|
||||
indirect, the ``QPDFObject`` the ``PointerHolder`` initially points to
|
||||
is a null pointer. In this case, the first attempt to access the
|
||||
underlying ``QPDFObject`` will result in the ``QPDFObject`` being
|
||||
value, copied, stored in containers, etc. with very low overhead. The
|
||||
``QPDFObjectHandle`` object contains an internal shared pointer to an
|
||||
underyling ``QPDFObject``. Instances of ``QPDFObjectHandle`` created
|
||||
by reading from a file will always contain a reference back to the
|
||||
``QPDF`` object from which they were created. A ``QPDFObjectHandle``
|
||||
may be direct or indirect. If indirect, the ``QPDFObject`` shared
|
||||
pointer is initially null. In this case, the first attempt to access
|
||||
the underlying ``QPDFObject`` will result in the ``QPDFObject`` being
|
||||
resolved via a call to the referenced ``QPDF`` instance. This makes it
|
||||
essentially impossible to make coding errors in which certain things
|
||||
will work for some PDF files and not for others based on which objects
|
||||
|
@ -248,17 +247,18 @@ During this process, the "``R``" keyword is recognized and an indirect
|
|||
|
||||
The ``QPDF::resolve()`` method, which is used to resolve an indirect
|
||||
object, may be invoked from the ``QPDFObjectHandle`` class. It first
|
||||
checks a cache to see whether this object has already been read. If not,
|
||||
it reads the object from the PDF file and caches it. It the returns the
|
||||
resulting ``QPDFObjectHandle``. The calling object handle then replaces
|
||||
its ``PointerHolder<QDFObject>`` with the one from the newly returned
|
||||
``QPDFObjectHandle``. In this way, only a single copy of any direct
|
||||
object need exist and clients can access objects transparently without
|
||||
knowing or caring whether they are direct or indirect objects.
|
||||
Additionally, no object is ever read from the file more than once. That
|
||||
means that only the portions of the PDF file that are actually needed
|
||||
are ever read from the input file, thus allowing the qpdf package to
|
||||
take advantage of this important design goal of PDF files.
|
||||
checks a cache to see whether this object has already been read. If
|
||||
not, it reads the object from the PDF file and caches it. It the
|
||||
returns the resulting ``QPDFObjectHandle``. The calling object handle
|
||||
then replaces its ``std::shared_ptr<QDFObject>`` with the one from the
|
||||
newly returned ``QPDFObjectHandle``. In this way, only a single copy
|
||||
of any direct object need exist and clients can access objects
|
||||
transparently without knowing or caring whether they are direct or
|
||||
indirect objects. Additionally, no object is ever read from the file
|
||||
more than once. That means that only the portions of the PDF file that
|
||||
are actually needed are ever read from the input file, thus allowing
|
||||
the qpdf package to take advantage of this important design goal of
|
||||
PDF files.
|
||||
|
||||
If the requested object is inside of an object stream, the object stream
|
||||
itself is first read into memory. Then the tokenizer reads objects from
|
||||
|
@ -762,40 +762,47 @@ Smart Pointers
|
|||
--------------
|
||||
|
||||
This section describes changes to the use of smart pointers that were
|
||||
made in qpdf 10.6.0 as well as some planned for 11.0.0.
|
||||
made in qpdf 10.6.0 and 11.0.0.
|
||||
|
||||
Starting in qpdf 11, ``PointerHolder`` will be replaced with
|
||||
In qpdf 11.0.0, ``PointerHolder`` was replaced with
|
||||
``std::shared_ptr`` in qpdf's public API. A backward-compatible
|
||||
``PointerHolder`` class will be provided that should make it possible
|
||||
for most code to remain unchanged. ``PointerHolder`` may eventually be
|
||||
``PointerHolder`` class has been provided that makes it possible for
|
||||
most code to remain unchanged. ``PointerHolder`` may eventually be
|
||||
removed from qpdf entirely, but this will not happen for a while to
|
||||
make it easier for people who need to support multiple versions of
|
||||
qpdf.
|
||||
|
||||
The ``POINTERHOLDER_TRANSITION`` preprocessor symbol has been
|
||||
introduced to help people transition from ``PointerHolder`` to
|
||||
``std::shared_ptr``. After qpdf 11 is released, to prepare for a
|
||||
future qpdf without ``PointerHolder`` and to let them know that it is
|
||||
no longer needed, a warning will be issued if
|
||||
``<qpdf/PointerHolder.hh>`` is included, though it will be possible to
|
||||
suppress the warning by defining ``POINTERHOLDER_TRANSITION``. In
|
||||
10.6.0, there are some steps you can perform to prepare, but no action
|
||||
is required.
|
||||
In 10.6.0, some enhancements were made to ``PointerHolder`` to ease
|
||||
the transition. These intermediate steps are relevant only for
|
||||
versions 10.6.0 through 10.6.3 but can still help with incremental
|
||||
modification of code.
|
||||
|
||||
The remainder of this section describes how to prepare if you want to
|
||||
eliminate ``PointerHolder`` from your code or what to do if you want
|
||||
to stick with the old interfaces.
|
||||
The ``POINTERHOLDER_TRANSITION`` preprocessor symbol was introduced in
|
||||
qpdf 10.6.0 to help people transition from ``PointerHolder`` to
|
||||
``std::shared_ptr``. If you don't define this, you will get a compiler
|
||||
warning. Defining it to any value will suppress the warning. An
|
||||
explanation appears below of the different possible values for this
|
||||
symbol and what they mean.
|
||||
|
||||
Changes in 10.6.0
|
||||
~~~~~~~~~~~~~~~~~
|
||||
Starting in qpdf 11.0.0, including ``<qpdf/PointerHolder.hh>`` defines
|
||||
the symbol ``POINTERHOLDER_IS_SHARED_POINTER``. This can be used with
|
||||
conditional compilation to make it possible to support different
|
||||
versions of qpdf.
|
||||
|
||||
In qpdf 10.6.0, the following changes have been made to
|
||||
``PointerHolder`` to make its behavior closer to that of
|
||||
``std::shared_ptr``:
|
||||
The rest of this section provides the details.
|
||||
|
||||
- ``get()`` has been added as an alternative to ``getPointer()``
|
||||
Transitional Enhancements to PointerHolder
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- ``use_count()`` has been added as an alternative to ``getRefcount()``
|
||||
In qpdf 10.6.0, some changes were to ``PointerHolder`` to make it
|
||||
easier to prepare for the transition to ``std::shared_ptr``. These
|
||||
enhancements also make it easier to incrementally upgrade your code.
|
||||
The following changes were made to ``PointerHolder`` to make its
|
||||
behavior closer to that of ``std::shared_ptr``:
|
||||
|
||||
- ``get()`` was added as an alternative to ``getPointer()``
|
||||
|
||||
- ``use_count()`` was added as an alternative to ``getRefcount()``
|
||||
|
||||
- A new global helper function ``make_pointer_holder`` behaves
|
||||
similarly to ``std::make_shared``, so you can use
|
||||
|
@ -807,7 +814,7 @@ In qpdf 10.6.0, the following changes have been made to
|
|||
counterpart to the newly added ``QUtil::make_shared_array`` method,
|
||||
which does the same thing with a ``std::shared_ptr``.
|
||||
|
||||
``PointerHolder`` has had a long-standing bug: a ``const
|
||||
``PointerHolder`` had a long-standing bug: a ``const
|
||||
PointerHolder<T>`` would only provide a ``T const*`` with its
|
||||
``getPointer`` method. This is incorrect and is not how standard
|
||||
library C++ smart pointers or regular pointers behave. The correct
|
||||
|
@ -873,16 +880,23 @@ preprocessor symbol or other C++ coding techniques.
|
|||
pointer. It also has the seldom-used ``getRefcount()`` method to get
|
||||
the reference count. ``std::shared_ptr<T>`` has ``get()`` and
|
||||
``use_count()``. In qpdf 10.6, ``PointerHolder<T>`` also has
|
||||
would not be an issue unless you did this in your own code.
|
||||
``get()`` and ``use_count()``.
|
||||
|
||||
Addressing the Differences
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you need to support versions of qpdf prior to qpdf 10.6, you don't
|
||||
*need* to take any action at this time, but it is recommended that you
|
||||
at least address the implicit constructor issue since this can be done
|
||||
without breaking backward compatibility. (Explicit construction of
|
||||
``PointerHolder<T>`` is and always has been allowed.)
|
||||
If you are not ready to take action yet, you can ``#define
|
||||
POINTERHOLDER_TRANSITION 0`` before including any qpdf header file or
|
||||
add the definition of that symbol to your build. This will provide the
|
||||
backward-compatible ``PointerHolder`` API without any deprecation
|
||||
warnings. This should be a temporary measure as ``PointerHolder`` may
|
||||
disappear in the future. If you need to be able to support newer and
|
||||
older versions of qpdf, there are other options, explained below.
|
||||
|
||||
Note that, even with ``0``, you should rebuild and test your code.
|
||||
There may be compiler errors if you have containers of
|
||||
``PointerHolder``, but most code should compile without any changes.
|
||||
There are no uses of containers of ``PointerHolder`` in qpdf's API.
|
||||
|
||||
There are two significant things you can do to minimize the impact of
|
||||
switching from ``PointerHolder`` to ``std::shared_ptr``:
|
||||
|
@ -908,31 +922,35 @@ without consulting this manual.
|
|||
- meaning
|
||||
|
||||
- - undefined
|
||||
- Same as ``0``, but starting with qpdf 11.0, issues a warning
|
||||
- Same as ``0`` but issues a warning
|
||||
|
||||
- - ``0``
|
||||
- Provide a backward compatible ``PointerHolder`` and suppress
|
||||
all deprecation warnings
|
||||
all deprecation warnings; supports all prior qpdf versions
|
||||
|
||||
- - ``1``
|
||||
- Make the ``PointerHolder<T>(T*)`` constructor explicit
|
||||
- Make the ``PointerHolder<T>(T*)`` constructor explicit;
|
||||
resulting code supports all prior qpdf versions
|
||||
|
||||
- - ``2``
|
||||
- Deprecate ``getPointer()`` and ``getRefcount()``
|
||||
- Deprecate ``getPointer()`` and ``getRefcount()``; requires
|
||||
qpdf 10.6.0 or later.
|
||||
|
||||
- - ``3``
|
||||
- Starting with qpdf 11.0, deprecate all uses of ``PointerHolder``
|
||||
- Deprecate all uses of ``PointerHolder``; requires qpdf 11.0.0
|
||||
or later
|
||||
|
||||
- - ``4``
|
||||
- Starting with qpdf 11.0, disable all functionality from
|
||||
``qpdf/PointerHolder.hh`` so that ``#include``-ing it has no
|
||||
effect.
|
||||
- Disable all functionality from ``qpdf/PointerHolder.hh`` so
|
||||
that ``#include``-ing it has no effect other than defining
|
||||
``POINTERHOLDER_IS_SHARED_POINTER``; requires qpdf 11.0.0 or
|
||||
later.
|
||||
|
||||
Based on the above, here is a procedure for preparing your code. This
|
||||
is the procedure that was used for the qpdf code itself.
|
||||
|
||||
If you need to support versions of qpdf prior to 10.6, you can still
|
||||
do these steps:
|
||||
You can do these steps without breaking support for qpdf versions
|
||||
before 10.6.0:
|
||||
|
||||
- Find all occurrences of ``PointerHolder`` in the code. See whether
|
||||
any of them can just be outright replaced with ``std::shared_ptr``
|
||||
|
@ -974,8 +992,9 @@ do these steps:
|
|||
auto p = std::unique_ptr<X[]>(new X[n]);
|
||||
|
||||
- If a ``PointerHolder<T>`` can't be replaced with a standard library
|
||||
smart pointer, perhaps it can be declared using ``auto`` or
|
||||
``decltype`` so that, when the qpdf API changes, your code will just
|
||||
smart pointer because it is used with an older qpdf API call,
|
||||
perhaps it can be declared using ``auto`` or ``decltype`` so that,
|
||||
when building with a newer qpdf API changes, your code will just
|
||||
need to be recompiled.
|
||||
|
||||
- ``#define POINTERHOLDER_TRANSITION 1`` to enable deprecation
|
||||
|
@ -1000,55 +1019,18 @@ do these steps:
|
|||
Other examples appear above.
|
||||
|
||||
If you need to support older versions of qpdf than 10.6, this is as
|
||||
far as you can go until qpdf 11 comes out.
|
||||
far as you can go without conditional compilation.
|
||||
|
||||
If you only need to support the latest version of qpdf, proceed as
|
||||
follows:
|
||||
|
||||
- ``#define POINTERHOLDER_TRANSITION 2`` to enable deprecation of
|
||||
``getPointer()`` and ``getRefcount()``
|
||||
|
||||
- Replace ``getPointer()`` with ``get()`` and ``getRefcount()`` with
|
||||
``use_count()``. These methods were not present prior to 10.6.0.
|
||||
|
||||
When you have gotten your code to compile cleanly with
|
||||
``POINTERHOLDER_TRANSITION=2``, you are well on your way to being
|
||||
ready for eliminating ``PointerHolder`` entirely after qpdf 11 is
|
||||
released.
|
||||
|
||||
After qpdf 11 is out
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In the 10.6 manual, this section represents a plan and is subject to
|
||||
change. However, it has been tested in practice using a version of the
|
||||
qpdf 11 ``PointerHolder`` on a branch, so it is likely to be accurate.
|
||||
In the meantime, think of this as a preview.
|
||||
|
||||
First, make sure you have done the steps in the 10.6 section. (Note:
|
||||
once qpdf 11 comes out, the goal is to not have to migrate to 10.6
|
||||
first, so it is likely that these sections will be combined.)
|
||||
|
||||
If you are explicitly choosing to stick with the backward compatible
|
||||
``PointerHolder`` for now, you should define
|
||||
``POINTERHOLDER_TRANSITION`` to ``0`` to suppress the warning from
|
||||
including ``qpdf/PointerHolder.hh``. Be aware that you may eventually
|
||||
have to deal with the transition, though the intention is to leave the
|
||||
compatibility layer in place for a while. You should rebuild and test
|
||||
your code. There may be compiler errors if you have containers of
|
||||
``PointerHolder``, but most code should compile without any changes.
|
||||
Even if you have errors, use of ``auto`` or ``decltype`` may enable
|
||||
you to write code that works with the old and new API without having
|
||||
to use conditional compilation. The
|
||||
``POINTERHOLDER_IS_SHARED_POINTER`` is defined in qpdf 11 if you
|
||||
``#include <qpdf/PointerHolder.hh>``.
|
||||
|
||||
If you want to support older versions of qpdf and still transition so
|
||||
that the backward-compatible ``PointerHolder`` is not in use, you can
|
||||
separate old code and new code by testing with the
|
||||
Starting in qpdf 11.0.0, including ``<qpdf/PointerHolder.hh>`` defines
|
||||
the symbol ``POINTERHOLDER_IS_SHARED_POINTER``. If you want to support
|
||||
older versions of qpdf and still transition so that the
|
||||
backward-compatible ``PointerHolder`` is not in use, you can separate
|
||||
old code and new code by testing with the
|
||||
``POINTERHOLDER_IS_SHARED_POINTER`` preprocessor symbol, as in
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
#include <qpdf/PointerHolder.hh>
|
||||
#ifdef POINTERHOLDER_IS_SHARED_POINTER
|
||||
std::shared_ptr<X> x;
|
||||
#else
|
||||
|
@ -1060,6 +1042,7 @@ or
|
|||
|
||||
.. code-block:: c++
|
||||
|
||||
#include <qpdf/PointerHolder.hh>
|
||||
#ifdef POINTERHOLDER_IS_SHARED_POINTER
|
||||
auto x_p = std::make_shared<X>();
|
||||
X* x = x_p.get();
|
||||
|
@ -1074,13 +1057,23 @@ If you don't need to support older versions of qpdf, you can proceed
|
|||
with these steps without protecting changes with the preprocessor
|
||||
symbol. Here are the remaining changes.
|
||||
|
||||
- Make sure you have a clean build with ``POINTERHOLDER_TRANSITION``
|
||||
set to ``2``. This means that you are using ``PointerHolder`` in a
|
||||
manner that is API-compatible with ``std::shared_ptr`` in all cases
|
||||
except for array pointers.
|
||||
- ``#define POINTERHOLDER_TRANSITION 2`` to enable deprecation of
|
||||
``getPointer()`` and ``getRefcount()``
|
||||
|
||||
- Replace ``getPointer()`` with ``get()`` and ``getRefcount()`` with
|
||||
``use_count()``. These methods were not present prior to 10.6.0.
|
||||
|
||||
When you have gotten your code to compile cleanly with
|
||||
``POINTERHOLDER_TRANSITION=2``, you are well on your way to being
|
||||
ready for eliminating ``PointerHolder`` entirely. The code at this
|
||||
point will not work with any qpdf version prior to 10.6.0.
|
||||
|
||||
To support qpdf 11.0.0 and newer and remove ``PointerHolder`` from
|
||||
your code, continue with the following steps:
|
||||
|
||||
- Replace all occurrences of ``PointerHolder`` with
|
||||
``std::shared_ptr`` except in ``#include <qpdf/PointerHolder.hh>``
|
||||
``std::shared_ptr`` except in the literal statement ``#include
|
||||
<qpdf/PointerHolder.hh>``
|
||||
|
||||
- Replace all occurrences of ``make_pointer_holder`` with
|
||||
``std::make_shared``
|
||||
|
|
Loading…
Reference in New Issue