summaryrefslogtreecommitdiff
path: root/src/ref_ptr.hh
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2015-01-18 18:23:58 +0000
committerMaxime Coste <frrrwww@gmail.com>2015-01-18 18:23:58 +0000
commit9b057896d4d28360d4ff950d01cda0fdba19d2a3 (patch)
treec7892541cabd2ad6b450a30f600e283683560182 /src/ref_ptr.hh
parentef26b77aa71ef339ac2d67c1f17c0e16990fa320 (diff)
Replace std::shared_ptr with homemade, intrusive, ref_ptr
That saves a lot of memory as sizeof(SharedString) is now one pointer less.
Diffstat (limited to 'src/ref_ptr.hh')
-rw-r--r--src/ref_ptr.hh65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/ref_ptr.hh b/src/ref_ptr.hh
new file mode 100644
index 00000000..7bd2ed83
--- /dev/null
+++ b/src/ref_ptr.hh
@@ -0,0 +1,65 @@
+#ifndef ref_ptr_hh_INCLUDED
+#define ref_ptr_hh_INCLUDED
+
+namespace Kakoune
+{
+
+template<typename T>
+struct ref_ptr
+{
+ ref_ptr() = default;
+ ref_ptr(T* ptr) : m_ptr(ptr) { acquire(); }
+ ~ref_ptr() { release(); }
+ ref_ptr(const ref_ptr& other) : m_ptr(other.m_ptr) { acquire(); }
+ ref_ptr(ref_ptr&& other) : m_ptr(other.m_ptr) { other.m_ptr = nullptr; }
+
+ ref_ptr& operator=(const ref_ptr& other)
+ {
+ release();
+ m_ptr = other.m_ptr;
+ acquire();
+ return *this;
+ }
+ ref_ptr& operator=(ref_ptr&& other)
+ {
+ release();
+ m_ptr = other.m_ptr;
+ other.m_ptr = nullptr;
+ return *this;
+ }
+
+ T* operator->() const { return m_ptr; }
+ T& operator*() const { return *m_ptr; }
+
+ T* get() const { return m_ptr; }
+
+ explicit operator bool() { return m_ptr; }
+
+ friend bool operator==(const ref_ptr& lhs, const ref_ptr& rhs)
+ {
+ return lhs.m_ptr == rhs.m_ptr;
+ }
+ friend bool operator!=(const ref_ptr& lhs, const ref_ptr& rhs)
+ {
+ return lhs.m_ptr != rhs.m_ptr;
+ }
+private:
+ T* m_ptr = nullptr;
+
+ void acquire()
+ {
+ if (m_ptr)
+ inc_ref_count(m_ptr);
+ }
+
+ void release()
+ {
+ if (m_ptr)
+ dec_ref_count(m_ptr);
+ m_ptr = nullptr;
+ }
+};
+
+}
+
+#endif // ref_ptr_hh_INCLUDED