Perceptual Color

constpropagatingrawpointer.h
1// SPDX-FileCopyrightText: Lukas Sommer <sommerluk@gmail.com>
2// SPDX-License-Identifier: BSD-2-Clause OR MIT
3
4#ifndef CONSTPROPAGATINGRAWPOINTER_H
5#define CONSTPROPAGATINGRAWPOINTER_H
6
7namespace PerceptualColor
8{
9/** @internal
10 *
11 * @brief A <tt>const</tt> propagating raw pointer
12 *
13 * With normal raw C++ pointers (and also with <tt>std::unique_ptr</tt>
14 * pointers), within <tt>const</tt> functions you can do non-const
15 * operations <em>on objects that a pointer points to</em>.
16 *
17 * <em>This</em> pointer type is different: It propagates the const-ness of
18 * the object members and propagates them to the call through the pointer;
19 * it will trigger a compiler error if non-cost access to object members
20 * or methods is done from within const functions. Apart from that, it
21 * behaves similar to raw pointers. For compatibility with raw pointers,
22 * it also casts implicitly to the corresponding raw pointer (but only
23 * within non-<tt>const</tt> contexts).
24 *
25 * Think of this template as a simple alternative to
26 * <tt>std::experimental::propagate_const&lt; T* &gt;</tt>
27 *
28 * Example code:
29 * @snippet testconstpropagatingrawpointer.cpp example
30 *
31 * @note Currently, this class does not implement assignment operators
32 * or assignment constructors. Once constructed, an instance of
33 * this class cannot be changed anymore.
34 *
35 * @note A @ref ConstPropagatingRawPointer pointer variable itself
36 * may not be const! (Otherwise, this would make <tt>const</tt>
37 * <em>all</em> access even to non-const functions of the pointed
38 * object.)
39 *
40 * @sa @ref ConstPropagatingUniquePointer
41 *
42 * @note There exist very sophisticated implementations like
43 * https://github.com/jbcoe/propagate_const but we use nevertheless
44 * our own light-wise implementation because this seems to be enough
45 * for our limited use case.
46 *
47 * @note This class could be replaced in the future by <tt>
48 * <a href="https://en.cppreference.com/w/cpp/experimental/propagate_const">
49 * std::experimental::propagate_const</a></tt> if this one ever becomes
50 * part of the C++ standard. (Experimental features however are optional
51 * for compilers, so not all of them implement them. Furthermore, they
52 * can still change. Therefore, we cannot use experimental features here.) */
53template<typename T>
54class ConstPropagatingRawPointer final
55{
56public:
57 /** @brief Default constructor
58 *
59 * Creates a pointer that points to <tt>nullptr</tt>. */
60 explicit ConstPropagatingRawPointer()
61 : m_pointer(nullptr)
62 {
63 }
64
65 /** @brief Constructor
66 *
67 * @param pointer Object to which to point */
68 explicit ConstPropagatingRawPointer(T *pointer)
69 : m_pointer(pointer)
70 {
71 }
72
73 /** @brief Default destructor */
74 ~ConstPropagatingRawPointer() noexcept = default;
75
76 /** @brief Non-const pointer operator
77 *
78 * @returns Non-const pointer operator */
79 [[nodiscard]] T *operator->()
80 {
81 return m_pointer;
82 }
83
84 /** @brief Const pointer operator
85 *
86 * @returns Const pointer */
87 [[nodiscard]] const T *operator->() const
88 {
89 return m_pointer;
90 }
91
92 /** @brief Non-const dereference operator
93 *
94 * @returns Non-const dereference operator */
95 [[nodiscard]] T &operator*()
96 {
97 return *m_pointer;
98 }
99
100 /** @brief Const dereference operator
101 *
102 * @returns Const dereference operator */
103 [[nodiscard]] const T &operator*() const
104 {
105 return *m_pointer;
106 }
107
108 /** @brief Cast to a normal raw pointer.
109 *
110 * @sa @ref toPointerToConstObject() */
111 [[nodiscard]] operator T *()
112 {
113 return m_pointer;
114 }
115
116 /** @brief Cast to a normal raw pointer that points to a const object.
117 *
118 * @returns Cast to a normal raw pointer that points to a const object.
119 *
120 * @sa @ref operator T *() */
121 // We could provide a const overload to operator T*() instead of
122 // providing this function with a strange name. But overloading
123 // operator T* leads to compile errors because of ambiguity
124 // on GCC and Clang when using this pointer within a “delete” statement.
125 // That’s confusing, therefore we should avoid it. So given this
126 // function this different name prevents automatic casts in non-cost
127 // objects, which also forbids deleting directly pointers of this
128 // type in non-const contexts, which is nice.
129 [[nodiscard]] const T *toPointerToConstObject() const
130 {
131 return m_pointer;
132 }
133
134private:
135 /** @brief Internal storage for the pointer */
136 T *m_pointer;
137};
138
139} // namespace PerceptualColor
140
141#endif // CONSTPROPAGATINGUNIQUEPOINTER_H
The namespace of this library.
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:18:38 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.