Skip to content

Commit

Permalink
A smart memory pointer.
Browse files Browse the repository at this point in the history
  • Loading branch information
kingToolbox committed Mar 11, 2021
1 parent 44cc3bb commit be6e770
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
140 changes: 140 additions & 0 deletions src/Utility/MemoryPointer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#ifndef MEMORYPOINTER_H
#define MEMORYPOINTER_H

#pragma once

#include <QtGlobal>

template <typename T>
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<T *>(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<void *>(uMemory.pointer));
uMemory = { 0 };
}
}

private:
union MemoryUnion {
quint64 value;

struct {
quint64 alloced : 1;
quint64 pointer : 48;
};
};
MemoryUnion uMemory;
};

template <class T>
inline bool operator==(const T *o, const MemoryPointer<T> &p) {
return o == p.operator->();
}

template<class T>
inline bool operator==(const MemoryPointer<T> &p, const T *o) {
return p.operator->() == o;
}

template <class T>
inline bool operator==(T *o, const MemoryPointer<T> &p) {
return o == p.operator->();
}

template<class T>
inline bool operator==(const MemoryPointer<T> &p, T *o) {
return p.operator->() == o;
}

template<class T>
inline bool operator==(const MemoryPointer<T> &lhs, const MemoryPointer<T> &rhs) {
return lhs.operator->() == rhs.operator->();
}

template <class T>
inline bool operator!=(const T *o, const MemoryPointer<T> &p) {
return o != p.operator->();
}

template<class T>
inline bool operator!= (const MemoryPointer<T> &p, const T *o) {
return p.operator->() != o;
}

template <class T>
inline bool operator!=(T *o, const MemoryPointer<T> &p) {
return o != p.operator->();
}

template<class T>
inline bool operator!= (const MemoryPointer<T> &p, T *o) {
return p.operator->() != o;
}

template<class T>
inline bool operator!= (const MemoryPointer<T> &lhs, const MemoryPointer<T> &rhs) {
return lhs.operator->() != rhs.operator->();
}

#endif // MEMORYPOINTER_H

0 comments on commit be6e770

Please sign in to comment.