#ifndef __UniquePointer_Include_H_ #define __UniquePointer_Include_H_ #include #include // https://en.cppreference.com/w/cpp/memory/unique_ptr namespace bse { template class unique_ptr { private: T* ptr = nullptr; // Forbid copying unique_ptr(const T& copy) = delete; unique_ptr& operator=(const unique_ptr& copy) = delete; public: // Construction unique_ptr() = default; unique_ptr(T* ptr) : ptr(std::move(ptr)) {} // Deletion ~unique_ptr() { delete ptr; } // Moving unique_ptr(unique_ptr&& move) noexcept { reset(move.release()); } unique_ptr& operator=(unique_ptr&& move) noexcept { reset(move.release()); return *this; } // Resetting: Replaces managed object, deleting the old one void reset(T* ptr) { delete this->ptr; this->ptr = ptr; } void reset() { reset(nullptr); } // Release: Releases ownership without deletion T* release() { // T* old = ptr; // ptr = nullptr; // return old; return std::exchange(ptr, nullptr); } // Nice to have operators T* operator->() { return ptr; } T& operator*() const { return *ptr; } explicit operator void*() const { return ptr; } explicit operator bool() const { return (ptr != nullptr); } }; // Unique Pointer for Arrays template class unique_ptr { private: T* ptr = nullptr; // unique_ptr(const T& copy) = delete; // unique_ptr& operator=(const unique_ptr& copy) = delete; public: unique_ptr() = default; unique_ptr(T* ptr) : ptr(std::move(ptr)) {} // Deletion ~unique_ptr() { delete[] ptr; } // Moving unique_ptr(unique_ptr&& move) noexcept { reset(move.release()); } unique_ptr& operator=(unique_ptr&& move) noexcept { reset(move.release()); return *this; } // Resetting: Replaces managed object, deleting the old one void reset(T* ptr) { delete this->ptr; this->ptr = ptr; } void reset() { reset(nullptr); } // Release: Releases ownership without deletion T* release() { // T* old = ptr; // ptr = nullptr; // return old; return std::exchange(ptr, nullptr); } // Nice to have operators T* operator->() = delete; T& operator*() const = delete; explicit operator void*() const { return ptr; } explicit operator bool() const { return (ptr != nullptr); } T& operator[](std::size_t i) { return ptr[i]; } }; // Allow initialization of unique_ptr with optional constructor arguments // and unique_ptr without constructor arguments template // We make the return type dependent on whether T is an array type or not typename std::enable_if::value, unique_ptr>::type make_unique(Args&&... args) { return unique_ptr(new T(std::forward(args)...)); } template typename std::enable_if::value, unique_ptr>::type make_unique(std::size_t size) { using bare_type = typename std::remove_extent::type; return unique_ptr(new bare_type[size]); } } // namespace bse #endif