aboutsummaryrefslogtreecommitdiff
path: root/src/libutil/ref.hh
diff options
context:
space:
mode:
authorRobert Hensing <robert@roberthensing.nl>2021-08-29 18:09:13 +0200
committerRobert Hensing <robert@roberthensing.nl>2021-08-29 18:11:58 +0200
commitf10465774fafaa2423cb05e02b38e03ed2abded7 (patch)
treece3c4e35b59ac3ad24c44b65d50ddd041fe70fcf /src/libutil/ref.hh
parentaf94b54db3a2be100731a215cb5e95f306471731 (diff)
Force all Pos* to be non-null
This fixes a class of crashes and introduces ptr<T> to make the code robust against this failure mode going forward. Thanks regnat for the idea of a ref<T> without overhead! Closes #4895 Closes #4893 Closes #5127 Closes #5113
Diffstat (limited to 'src/libutil/ref.hh')
-rw-r--r--src/libutil/ref.hh43
1 files changed, 43 insertions, 0 deletions
diff --git a/src/libutil/ref.hh b/src/libutil/ref.hh
index 2549ef496..d6bf53bb8 100644
--- a/src/libutil/ref.hh
+++ b/src/libutil/ref.hh
@@ -99,4 +99,47 @@ make_ref(Args&&... args)
return ref<T>(p);
}
+
+/* A non-nullable pointer.
+ This is similar to a C++ "& reference", but mutable.
+ This is similar to ref<T> but backed by a regular pointer instead of a smart pointer.
+ */
+template<typename T>
+class ptr {
+private:
+ T * p;
+
+public:
+ ptr<T>(const ptr<T> & r)
+ : p(r.p)
+ { }
+
+ explicit ptr<T>(T * p)
+ : p(p)
+ {
+ if (!p)
+ throw std::invalid_argument("null pointer cast to ptr");
+ }
+
+ T* operator ->() const
+ {
+ return &*p;
+ }
+
+ T& operator *() const
+ {
+ return *p;
+ }
+
+ bool operator == (const ptr<T> & other) const
+ {
+ return p == other.p;
+ }
+
+ bool operator != (const ptr<T> & other) const
+ {
+ return p != other.p;
+ }
+};
+
}