Skip to content

Instantly share code, notes, and snippets.

@goldsborough
Created October 27, 2015 23:06
Show Gist options
  • Save goldsborough/f8fd3c6bfbd5e71ee222 to your computer and use it in GitHub Desktop.
Save goldsborough/f8fd3c6bfbd5e71ee222 to your computer and use it in GitHub Desktop.
A smart unique-pointer class.
template<typename T>
class UniquePointer
{
public:
using pointer_t = T*;
using const_pointer_t = const T*;
using reference_t = T&;
using const_reference_t = const T&;
using deleter_t = std::function<void(T*)>;
explicit UniquePointer(pointer_t pointer = nullptr,
const deleter_t& deleter = std::default_delete<T>()) noexcept
: _pointer(pointer)
, _deleter(deleter)
{ }
UniquePointer(const UniquePointer& other) = delete;
template<typename U>
UniquePointer(const UniquePointer<U>& other) = delete;
UniquePointer(UniquePointer&& other) noexcept
: UniquePointer()
{
swap(other);
}
template<typename U>
UniquePointer(UniquePointer<U>&& other) noexcept
: UniquePointer()
{
swap(other);
}
UniquePointer& operator=(UniquePointer other) noexcept
{
swap(other);
return *this;
}
template<typename U>
UniquePointer& operator=(UniquePointer<U> other) noexcept
{
swap(other);
return *this;
}
void swap(UniquePointer& other) noexcept
{
// Enable ADL
using std::swap;
swap(_pointer, other._pointer);
swap(_deleter, other._deleter);
}
template<typename U>
void swap(UniquePointer<U>& other) noexcept
{
// Enable ADL
using std::swap;
swap(_pointer, other._pointer);
}
template<typename U, typename V>
friend void swap(UniquePointer<U>& first, UniquePointer<V>& second) noexcept
{
first.swap(second);
}
~UniquePointer()
{
_deleter(_pointer);
}
operator bool() const
{
return _pointer != nullptr;
}
template<typename U>
bool operator==(const UniquePointer<U>& other)
{
return _pointer == other._pointer;
}
template<typename U>
bool operator!=(const UniquePointer<U>& other)
{
return _pointer != other._pointer;
}
template<typename U>
bool operator<(const UniquePointer<U>& other)
{
return _pointer < other._pointer;
}
template<typename U>
bool operator>(const UniquePointer<U>& other)
{
return _pointer > other._pointer;
}
template<typename U>
bool operator<=(const UniquePointer<U>& other)
{
return _pointer <= other._pointer;
}
template<typename U>
bool operator>=(const UniquePointer<U>& other)
{
return _pointer >= other._pointer;
}
reference_t operator*()
{
return *_pointer;
}
const_reference_t operator*() const
{
return *_pointer;
}
pointer_t operator->()
{
return _pointer;
}
const_pointer_t operator->() const
{
return _pointer;
}
pointer_t release() const
{
auto pointer = _pointer;
_pointer = nullptr;
return pointer;
}
void reset(pointer_t new_pointer = nullptr)
{
delete _pointer;
_pointer = new_pointer;
}
pointer_t get()
{
return _pointer;
}
const_pointer_t get() const
{
return _pointer;
}
const deleter_t& deleter() const
{
return _deleter;
}
private:
pointer_t _pointer;
deleter_t _deleter;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment