From be6e770876f5aad290bf5b7109ca1aa306bf02cf Mon Sep 17 00:00:00 2001 From: KingToolbox Date: Thu, 11 Mar 2021 23:23:21 +0800 Subject: [PATCH] A smart memory pointer. --- src/README.md | 4 ++ src/Utility/MemoryPointer.h | 140 ++++++++++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 src/Utility/MemoryPointer.h diff --git a/src/README.md b/src/README.md index 35db2ac..5bbb954 100644 --- a/src/README.md +++ b/src/README.md @@ -30,6 +30,10 @@ A quick circular buffer template class. A very safe encryption class using the PBKDF2-algorithm as defined in RFC 8018. WindTerm uses this class together with the user's master password to protect user data, including passwords, private keys and so on. +## Utility/MemoryPointer.h + +A smart memory pointer. + ## Utility/ScopeGuard.h A class of which the sole purpose is to run the function f in its destructor. This is useful for guaranteeing your cleanup code is executed. diff --git a/src/Utility/MemoryPointer.h b/src/Utility/MemoryPointer.h new file mode 100644 index 0000000..b5edb07 --- /dev/null +++ b/src/Utility/MemoryPointer.h @@ -0,0 +1,140 @@ +#ifndef MEMORYPOINTER_H +#define MEMORYPOINTER_H + +#pragma once + +#include + +template +struct MemoryPointer { + typedef decltype(nullptr) nullptr_t; + +public: + MemoryPointer() + : uMemory({ 0 }) + {} + + MemoryPointer(const MemoryPointer &other) = delete; + MemoryPointer &MemoryPointer::operator=(const MemoryPointer &other) = delete; + + MemoryPointer &MemoryPointer::operator=(nullptr_t) noexcept { + free(); + + uMemory = { 0 }; + return (*this); + } + + MemoryPointer(MemoryPointer &&other) noexcept { + uMemory = other.uMemory; + other.uMemory = { 0 }; + } + + MemoryPointer& MemoryPointer::operator=(MemoryPointer &&other) noexcept { + if (this != &other) { + free(); + + uMemory = other.uMemory; + other.uMemory = { 0 }; + } + return (*this); + } + + ~MemoryPointer() { + free(); + } + + inline T *data() const { + return static_cast(uMemory.pointer); + } + + inline T *operator->() const { + return data(); + } + + inline T &operator*() const { + return *data(); + } + + inline operator T*() const { + return data(); + } + + inline operator bool() const noexcept { + return data() != nullptr; + } + + inline bool isNull() const { + return uMemory.pointer == NULL; + } + +private: + void free() { + if (uMemory.alloced) { + ::free(reinterpret_cast(uMemory.pointer)); + uMemory = { 0 }; + } + } + +private: + union MemoryUnion { + quint64 value; + + struct { + quint64 alloced : 1; + quint64 pointer : 48; + }; + }; + MemoryUnion uMemory; +}; + +template +inline bool operator==(const T *o, const MemoryPointer &p) { + return o == p.operator->(); +} + +template +inline bool operator==(const MemoryPointer &p, const T *o) { + return p.operator->() == o; +} + +template +inline bool operator==(T *o, const MemoryPointer &p) { + return o == p.operator->(); +} + +template +inline bool operator==(const MemoryPointer &p, T *o) { + return p.operator->() == o; +} + +template +inline bool operator==(const MemoryPointer &lhs, const MemoryPointer &rhs) { + return lhs.operator->() == rhs.operator->(); +} + +template +inline bool operator!=(const T *o, const MemoryPointer &p) { + return o != p.operator->(); +} + +template +inline bool operator!= (const MemoryPointer &p, const T *o) { + return p.operator->() != o; +} + +template +inline bool operator!=(T *o, const MemoryPointer &p) { + return o != p.operator->(); +} + +template +inline bool operator!= (const MemoryPointer &p, T *o) { + return p.operator->() != o; +} + +template +inline bool operator!= (const MemoryPointer &lhs, const MemoryPointer &rhs) { + return lhs.operator->() != rhs.operator->(); +} + +#endif // MEMORYPOINTER_H \ No newline at end of file