GiNaC 1.8.7
ptr.h
Go to the documentation of this file.
1
5/*
6 * GiNaC Copyright (C) 1999-2023 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, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#ifndef GINAC_PTR_H
24#define GINAC_PTR_H
25
26#include "assertion.h"
27
28#include <cstddef> // for size_t
29#include <functional>
30#include <iosfwd>
31
32namespace GiNaC {
33
36public:
37 refcounted() noexcept : refcount(0) {}
38
39 unsigned int add_reference() noexcept { return ++refcount; }
40 unsigned int remove_reference() noexcept { return --refcount; }
41 unsigned int get_refcount() const noexcept { return refcount; }
42 void set_refcount(unsigned int r) noexcept { refcount = r; }
43
44private:
45 unsigned int refcount;
46};
47
48
56template <class T> class ptr {
57 friend struct std::less<ptr<T>>;
58
59 // NB: This implementation of reference counting is not thread-safe.
60 // The reference counter needs to be incremented/decremented atomically,
61 // and makewritable() requires locking.
62
63public:
64 // no default ctor: a ptr is never unbound
65
67 ptr(T *t) noexcept : p(t) { GINAC_ASSERT(p); p->set_refcount(1); }
68
70 explicit ptr(T &t) noexcept : p(&t) { p->add_reference(); }
71
72 ptr(const ptr & other) noexcept : p(other.p) { p->add_reference(); }
73
75 {
76 if (p->remove_reference() == 0)
77 delete p;
78 }
79
80 ptr &operator=(const ptr & other)
81 {
82 // NB1: Must first add reference to "other", since other might be *this.
83 // NB2: Cache other.p, because if "other" is a subexpression of p,
84 // deleting p will also invalidate "other".
85 T *otherp = other.p;
86 otherp->add_reference();
87 if (p->remove_reference() == 0)
88 delete p;
89 p = otherp;
90 return *this;
91 }
92
93 T &operator*() const noexcept { return *p; }
94 T *operator->() const noexcept { return p; }
95
96 friend inline T *get_pointer(const ptr & x) noexcept { return x.p; }
97
101 {
102 if (p->get_refcount() > 1) {
103 T *p2 = p->duplicate();
104 p2->set_refcount(1);
105 p->remove_reference();
106 p = p2;
107 }
108 }
109
111 void swap(ptr & other) noexcept
112 {
113 T *t = p;
114 p = other.p;
115 other.p = t;
116 }
117
118 // ptr<>s are always supposed to be bound to a valid object, so we don't
119 // provide support for "if (p)", "if (!p)", "if (p==0)" and "if (p!=0)".
120 // We do, however, provide support for comparing ptr<>s with other ptr<>s
121 // to different (probably derived) types and raw pointers.
122
123 template <class U>
124 bool operator==(const ptr<U> & rhs) const noexcept { return p == get_pointer(rhs); }
125
126 template <class U>
127 bool operator!=(const ptr<U> & rhs) const noexcept { return p != get_pointer(rhs); }
128
129 template <class U>
130 inline friend bool operator==(const ptr & lhs, const U * rhs) noexcept { return lhs.p == rhs; }
131
132 template <class U>
133 inline friend bool operator!=(const ptr & lhs, const U * rhs) noexcept { return lhs.p != rhs; }
134
135 template <class U>
136 inline friend bool operator==(const U * lhs, const ptr & rhs) noexcept { return lhs == rhs.p; }
137
138 template <class U>
139 inline friend bool operator!=(const U * lhs, const ptr & rhs) noexcept { return lhs != rhs.p; }
140
141 inline friend std::ostream & operator<<(std::ostream & os, const ptr<T> & rhs)
142 {
143 os << rhs.p;
144 return os;
145 }
146
147private:
148 T *p;
149};
150
151} // namespace GiNaC
152
153
154namespace std {
155
158template <class T> struct less<GiNaC::ptr<T>> {
159 bool operator()(const GiNaC::ptr<T> &lhs, const GiNaC::ptr<T> &rhs) const
160 {
161 return less<T*>()(lhs.p, rhs.p);
162 }
163};
164
165} // namespace std
166
167#endif // ndef GINAC_PTR_H
Assertion macro definition.
#define GINAC_ASSERT(X)
Assertion macro for checking invariances.
Definition: assertion.h:33
Class of (intrusively) reference-counted pointers that support copy-on-write semantics.
Definition: ptr.h:56
friend bool operator==(const U *lhs, const ptr &rhs) noexcept
Definition: ptr.h:136
bool operator!=(const ptr< U > &rhs) const noexcept
Definition: ptr.h:127
friend bool operator!=(const ptr &lhs, const U *rhs) noexcept
Definition: ptr.h:133
~ptr()
Definition: ptr.h:74
friend bool operator!=(const U *lhs, const ptr &rhs) noexcept
Definition: ptr.h:139
ptr(T *t) noexcept
Bind ptr to newly created object, start reference counting.
Definition: ptr.h:67
friend std::ostream & operator<<(std::ostream &os, const ptr< T > &rhs)
Definition: ptr.h:141
T * p
Definition: ptr.h:148
bool operator==(const ptr< U > &rhs) const noexcept
Definition: ptr.h:124
ptr(const ptr &other) noexcept
Definition: ptr.h:72
void swap(ptr &other) noexcept
Swap the bound object of this ptr with another ptr.
Definition: ptr.h:111
T * operator->() const noexcept
Definition: ptr.h:94
void makewritable()
Announce your intention to modify the object bound to this ptr.
Definition: ptr.h:100
ptr & operator=(const ptr &other)
Definition: ptr.h:80
friend bool operator==(const ptr &lhs, const U *rhs) noexcept
Definition: ptr.h:130
T & operator*() const noexcept
Definition: ptr.h:93
friend T * get_pointer(const ptr &x) noexcept
Definition: ptr.h:96
ptr(T &t) noexcept
Bind ptr to existing reference-counted object.
Definition: ptr.h:70
Base class for reference-counted objects.
Definition: ptr.h:35
unsigned int refcount
reference counter
Definition: ptr.h:45
void set_refcount(unsigned int r) noexcept
Definition: ptr.h:42
unsigned int get_refcount() const noexcept
Definition: ptr.h:41
unsigned int add_reference() noexcept
Definition: ptr.h:39
refcounted() noexcept
Definition: ptr.h:37
unsigned int remove_reference() noexcept
Definition: ptr.h:40
ex x
Definition: factor.cpp:1610
size_t r
Definition: factor.cpp:757
Definition: add.cpp:38
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:159

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