Perceptual Color

constpropagatinguniquepointer.h
1// SPDX-FileCopyrightText: Lukas Sommer <sommerluk@gmail.com>
2// SPDX-License-Identifier: BSD-2-Clause OR MIT
3
4#ifndef CONSTPROPAGATINGUNIQUEPOINTER_H
5#define CONSTPROPAGATINGUNIQUEPOINTER_H
6
7#include "importexport.h"
8#include <memory>
9
10namespace PerceptualColor
11{
12/** @internal
13 *
14 * @brief A <tt>const</tt> propagating <tt>std::unique_ptr</tt>
15 *
16 * With normal <tt>std::unique_ptr</tt> pointers (and also with raw
17 * C++ pointers), within <tt>const</tt> functions you can do non-const
18 * operations <em>on objects that a pointer points to</em>.
19 *
20 * <em>This</em> pointer type is different: It propagates the constness of
21 * the object members and propagates them to the call through the pointer;
22 * it will trigger a compiler error if non-cost access to object members
23 * or methods is done from within const functions. Apart from that, it
24 * behaves like <tt>std::unique_ptr</tt>.
25 *
26 * Think of this template as a simple alternative to
27 * <tt>std::experimental::propagate_const&lt; std::unique_ptr&lt;T&gt; &gt;</tt>
28 *
29 * Example code:
30 * @snippet testconstpropagatinguniquepointer.cpp example
31 *
32 * Currently, move-assignment is not supported. Use
33 * <tt>std::unique_prt::reset()</tt> instead. As there is no
34 * support for deleters anyway, this should be equivalent.
35 *
36 * @note A @ref ConstPropagatingUniquePointer pointer variable itself
37 * may not be const! @internal (Otherwise, this would make <tt>const</tt>
38 * <em>all</em> access even to non-const functions of the pointed
39 * object.) @endinternal
40 *
41 * @internal
42 *
43 * @sa @ref ConstPropagatingRawPointer
44 *
45 * This class inherits privately <tt>std::shared_ptr</tt> and not
46 * <tt>std::unique_ptr</tt> because the latter will not compile on
47 * the MSVC compiler when used with incomplete types, which is however
48 * necessary for usage within @ref pimpl.
49 *
50 * @note This class could be replaced in the future by <tt>
51 * <a href="https://en.cppreference.com/w/cpp/experimental/propagate_const">
52 * std::experimental::propagate_const</a></tt> if this one ever becomes
53 * part of the C++ standard. (Experimental features however are optional
54 * for compilers, so not all of them implement them. Furthermore, they
55 * can still change. Therefore, we cannot use experimental features here.)
56 *
57 * @todo Would it be better to include (or link to)
58 * https://github.com/jbcoe/propagate_const instead of having our own
59 * implementation? Or remove propagate_const header from this library? */
60// NOTE No PERCEPTUALCOLOR_IMPORTEXPORT for generic template definitions!
61template<typename T>
62class ConstPropagatingUniquePointer : private std::shared_ptr<T>
63{
64public:
65 /** @brief Default constructor
66 *
67 * Creates a pointer that points to <tt>nullptr</tt>. */
68 explicit ConstPropagatingUniquePointer()
69 : std::shared_ptr<T>(nullptr)
70 {
71 }
72
73 /** @brief Constructor
74 *
75 * @param pointerToObject Object to which to point */
76 explicit ConstPropagatingUniquePointer(T *pointerToObject)
77 : std::shared_ptr<T>(pointerToObject)
78 {
79 }
80
81 /** @brief Default destructor
82 *
83 * This destructor is not marked as <tt>override</tt> because the
84 * base class’s destructor is not virtual.*/
85 ~ConstPropagatingUniquePointer() noexcept = default;
86
87 // No copy/move assignment or constructor.
88 ConstPropagatingUniquePointer(const ConstPropagatingUniquePointer &) = delete;
89 ConstPropagatingUniquePointer(ConstPropagatingUniquePointer &&) = delete;
90 ConstPropagatingUniquePointer &operator=(const ConstPropagatingUniquePointer &) = delete; // clazy:exclude=function-args-by-value
91 ConstPropagatingUniquePointer &operator=(ConstPropagatingUniquePointer &&) = delete;
92
93 /** @brief Non-const pointer operator
94 *
95 * @returns Non-const pointer operator */
96 [[nodiscard]] T *operator->()
97 {
98 // cppcheck-suppress CastIntegerToAddressAtReturn // false positive
99 return std::shared_ptr<T>::operator->();
100 }
101
102 /** @brief Const pointer operator
103 *
104 * @returns Const pointer */
105 [[nodiscard]] const T *operator->() const
106 {
107 // cppcheck-suppress CastIntegerToAddressAtReturn // false positive
108 return std::shared_ptr<T>::operator->();
109 }
110
111 /** @brief Non-const dereference operator
112 *
113 * @returns Non-const dereference operator */
114 [[nodiscard]] T &operator*()
115 {
116 // cppcheck-suppress returnTempReference // false positive
117 return std::shared_ptr<T>::operator*();
118 }
119
120 /** @brief Const dereference operator
121 *
122 * @returns Const dereference operator */
123 [[nodiscard]] const T &operator*() const
124 {
125 // cppcheck-suppress returnTempReference // false positive
126 return std::shared_ptr<T>::operator*();
127 }
128
129 /** @brief Deletes the previously managed object (if any) and starts
130 * to manage a new object.
131 *
132 * @param newObject The new object that will be managed. Can be
133 * <tt>nullptr</tt> to not manage any object anymore. */
134 void reset(T *newObject = nullptr)
135 {
136 std::shared_ptr<T>::reset(newObject);
137 }
138
139 /** @brief Swaps the managed objects.
140 *
141 * @param other Another @ref ConstPropagatingUniquePointer object to
142 * swap the managed object with. */
143 void swap(ConstPropagatingUniquePointer &other)
144 {
145 std::shared_ptr<T>::swap(other);
146 }
147
148 /** @brief Returns a pointer to the managed object or <tt>nullptr</tt> if
149 * no object is owned.
150 *
151 * @returns A pointer to the managed object or <tt>nullptr</tt> if
152 * no object is owned. */
153 [[nodiscard]] T *get()
154 {
155 // cppcheck-suppress CastIntegerToAddressAtReturn // false positive
156 return std::shared_ptr<T>::get();
157 }
158};
159
160} // namespace PerceptualColor
161
162#endif // CONSTPROPAGATINGUNIQUEPOINTER_H
This file provides support for C++ symbol import and export.
The namespace of this library.
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri May 24 2024 11:48:43 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.