GiNaC 1.8.10
ptr.h
Go to the documentation of this file.
1
5/*
6 * GiNaC Copyright (C) 1999-2026 Johannes Gutenberg University Mainz, Germany
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22#ifndef GINAC_PTR_H
23#define GINAC_PTR_H
24
25#include "assertion.h"
26
27#include <cstddef> // for size_t
28#include <functional>
29#include <iosfwd>
30
31namespace GiNaC {
32
35public:
36 refcounted() noexcept : refcount(0) {}
37
38 unsigned int add_reference() noexcept { return ++refcount; }
39 unsigned int remove_reference() noexcept { return --refcount; }
40 unsigned int get_refcount() const noexcept { return refcount; }
41 void set_refcount(unsigned int r) noexcept { refcount = r; }
42
43private:
44 unsigned int refcount;
45};
46
47
55template <class T> class ptr {
56 friend struct std::less<ptr<T>>;
57
58 // NB: This implementation of reference counting is not thread-safe.
59 // The reference counter needs to be incremented/decremented atomically,
60 // and makewritable() requires locking.
61
62public:
63 // no default ctor: a ptr is never unbound
64
66 ptr(T *t) noexcept : p(t) { GINAC_ASSERT(p); p->set_refcount(1); }
67
69 explicit ptr(T &t) noexcept : p(&t) { p->add_reference(); }
70
71 ptr(const ptr & other) noexcept : p(other.p) { p->add_reference(); }
72
74 {
75 if (p->remove_reference() == 0)
76 delete p;
77 }
78
79 ptr &operator=(const ptr & other)
80 {
81 // NB1: Must first add reference to "other", since other might be *this.
82 // NB2: Cache other.p, because if "other" is a subexpression of p,
83 // deleting p will also invalidate "other".
84 T *otherp = other.p;
85 otherp->add_reference();
86 if (p->remove_reference() == 0)
87 delete p;
88 p = otherp;
89 return *this;
90 }
91
92 T &operator*() const noexcept { return *p; }
93 T *operator->() const noexcept { return p; }
94
95 friend inline T *get_pointer(const ptr & x) noexcept { return x.p; }
96
100 {
101 if (p->get_refcount() > 1) {
102 T *p2 = p->duplicate();
103 p2->set_refcount(1);
104 p->remove_reference();
105 p = p2;
106 }
107 }
108
110 void swap(ptr & other) noexcept
111 {
112 T *t = p;
113 p = other.p;
114 other.p = t;
115 }
116
117 // ptr<>s are always supposed to be bound to a valid object, so we don't
118 // provide support for "if (p)", "if (!p)", "if (p==0)" and "if (p!=0)".
119 // We do, however, provide support for comparing ptr<>s with other ptr<>s
120 // to different (probably derived) types and raw pointers.
121
122 template <class U>
123 bool operator==(const ptr<U> & rhs) const noexcept { return p == get_pointer(rhs); }
124
125 template <class U>
126 bool operator!=(const ptr<U> & rhs) const noexcept { return p != get_pointer(rhs); }
127
128 template <class U>
129 inline friend bool operator==(const ptr & lhs, const U * rhs) noexcept { return lhs.p == rhs; }
130
131 template <class U>
132 inline friend bool operator!=(const ptr & lhs, const U * rhs) noexcept { return lhs.p != rhs; }
133
134 template <class U>
135 inline friend bool operator==(const U * lhs, const ptr & rhs) noexcept { return lhs == rhs.p; }
136
137 template <class U>
138 inline friend bool operator!=(const U * lhs, const ptr & rhs) noexcept { return lhs != rhs.p; }
139
140 inline friend std::ostream & operator<<(std::ostream & os, const ptr<T> & rhs)
141 {
142 os << rhs.p;
143 return os;
144 }
145
146private:
147 T *p;
148};
149
150} // namespace GiNaC
151
152
153namespace std {
154
157template <class T> struct less<GiNaC::ptr<T>> {
158 bool operator()(const GiNaC::ptr<T> &lhs, const GiNaC::ptr<T> &rhs) const
159 {
160 return less<T*>()(lhs.p, rhs.p);
161 }
162};
163
164} // namespace std
165
166#endif // ndef GINAC_PTR_H
Assertion macro definition.
#define GINAC_ASSERT(X)
Assertion macro for checking invariances.
Definition assertion.h:32
Class of (intrusively) reference-counted pointers that support copy-on-write semantics.
Definition ptr.h:55
friend bool operator==(const U *lhs, const ptr &rhs) noexcept
Definition ptr.h:135
bool operator!=(const ptr< U > &rhs) const noexcept
Definition ptr.h:126
friend bool operator!=(const ptr &lhs, const U *rhs) noexcept
Definition ptr.h:132
~ptr()
Definition ptr.h:73
friend bool operator!=(const U *lhs, const ptr &rhs) noexcept
Definition ptr.h:138
ptr(T *t) noexcept
Bind ptr to newly created object, start reference counting.
Definition ptr.h:66
friend std::ostream & operator<<(std::ostream &os, const ptr< T > &rhs)
Definition ptr.h:140
T * p
Definition ptr.h:147
bool operator==(const ptr< U > &rhs) const noexcept
Definition ptr.h:123
ptr(const ptr &other) noexcept
Definition ptr.h:71
void swap(ptr &other) noexcept
Swap the bound object of this ptr with another ptr.
Definition ptr.h:110
T * operator->() const noexcept
Definition ptr.h:93
void makewritable()
Announce your intention to modify the object bound to this ptr.
Definition ptr.h:99
ptr & operator=(const ptr &other)
Definition ptr.h:79
friend bool operator==(const ptr &lhs, const U *rhs) noexcept
Definition ptr.h:129
T & operator*() const noexcept
Definition ptr.h:92
friend T * get_pointer(const ptr &x) noexcept
Definition ptr.h:95
ptr(T &t) noexcept
Bind ptr to existing reference-counted object.
Definition ptr.h:69
Base class for reference-counted objects.
Definition ptr.h:34
unsigned int refcount
reference counter
Definition ptr.h:44
void set_refcount(unsigned int r) noexcept
Definition ptr.h:41
unsigned int get_refcount() const noexcept
Definition ptr.h:40
unsigned int add_reference() noexcept
Definition ptr.h:38
refcounted() noexcept
Definition ptr.h:36
unsigned int remove_reference() noexcept
Definition ptr.h:39
ex x
Definition factor.cpp:1609
size_t r
Definition factor.cpp:756
Definition add.cpp:35
ex rhs(const ex &thisex)
Definition ex.h:832
ex lhs(const ex &thisex)
Definition ex.h:829
Definition ex.h:987
bool operator()(const GiNaC::ptr< T > &lhs, const GiNaC::ptr< T > &rhs) const
Definition ptr.h:158

This page is part of the GiNaC developer's reference. It was generated automatically by doxygen. For an introduction, see the tutorial.