Created
December 21, 2014 10:26
-
-
Save cjxgm/1458c06e38e31cb937b8 to your computer and use it in GitHub Desktop.
unique_pod, just like unique_ptr but is for POD
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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