Skip to content

Instantly share code, notes, and snippets.

@cjxgm
Created December 21, 2014 10:26
Show Gist options
  • Save cjxgm/1458c06e38e31cb937b8 to your computer and use it in GitHub Desktop.
Save cjxgm/1458c06e38e31cb937b8 to your computer and use it in GitHub Desktop.
unique_pod, just like unique_ptr but is for POD
#include <iostream>
using std::cin;
using std::cout;
using std::cerr;
using std::endl;
#include <type_traits>
namespace tue
{
template <class T>
struct no_delete
{
void operator () (T) const {}
};
template <class T=void>
struct default_tag {};
template <class T, class Deleter=no_delete<T>, class Tag=default_tag<T>>
struct unique_pod
{
static_assert(std::is_pod<T>{}, "T must be a POD");
using element_type = T;
using deleter_type = Deleter;
using tag_type = Tag;
private:
element_type element;
deleter_type deleter;
bool managed{false};
using self = unique_pod;
using ref = self &;
using cref = self const&;
using rref = self &&;
public:
unique_pod() = default;
unique_pod(element_type x, deleter_type del={}) : element(x), deleter(del), managed(true) {}
~unique_pod() { if (managed) deleter(element); }
unique_pod(cref other) = delete;
unique_pod(rref other) : element(other.element), deleter(other.deleter), managed(other.managed) { other.managed = false; }
auto& operator = (cref other) = delete;
auto& operator = (rref other) { self x{std::move(other)}; swap(x); return *this; }
auto& operator = (element_type x) { reset(x); return *this; }
void swap(ref other)
{
std::swap(element, other.element);
std::swap(deleter, other.deleter);
std::swap(managed, other.managed);
}
auto release() { managed = false; return get(); }
void reset(element_type x) { self other{x}; swap(other); }
void reset() { unique_pod other; swap(other); }
auto get() const { return element; }
auto & get_deleter() { return deleter; }
auto const& get_deleter() const { return deleter; }
operator bool () const { return managed; }
};
}
int main()
{
auto print = [](int x) { cout << x << endl; };
tue::unique_pod<int, decltype(print)> x{3, print};
x = 30;
auto y = std::move(x);
x = 40;
y = std::move(x);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment