ifd_pointer.hpp 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. #pragma once
  2. namespace stream { namespace detail {
  3. class ifd_pointer {
  4. private:
  5. void * (*copy)(void *){nullptr};
  6. void (*destroy)(void *){nullptr};
  7. void * ptr{nullptr};
  8. public:
  9. template <typename T>
  10. ifd_pointer(T && value)
  11. : copy(&ifd_pointer::copy_<T>), destroy(&ifd_pointer::destroy_<T>),
  12. ptr(copy(&value)) {}
  13. ifd_pointer() = default;
  14. ifd_pointer(ifd_pointer const & other)
  15. : copy(other.copy), destroy(other.destroy), ptr(copy(other.ptr)) {}
  16. ifd_pointer(ifd_pointer && other) {
  17. *this = std::forward<ifd_pointer>(other);
  18. }
  19. ifd_pointer & operator=(ifd_pointer const & other) {
  20. return *this = ifd_pointer(other);
  21. }
  22. ~ifd_pointer() {
  23. if (destroy) destroy(ptr);
  24. }
  25. ifd_pointer & operator=(ifd_pointer && other) {
  26. swap(*this, other);
  27. return *this;
  28. }
  29. void * get() const { return ptr; }
  30. private:
  31. friend void swap(ifd_pointer & lhs, ifd_pointer & rhs) {
  32. using ::std::swap;
  33. swap(lhs.copy, rhs.copy);
  34. swap(lhs.destroy, rhs.destroy);
  35. swap(lhs.ptr, rhs.ptr);
  36. }
  37. template <typename T> static void * copy_(void * p) {
  38. return (void *)new T(*(T *)(p));
  39. }
  40. template <typename T> static void destroy_(void * p) { delete (T *)(p); }
  41. };
  42. }}