203 lines
4.2 KiB
Plaintext
203 lines
4.2 KiB
Plaintext
#pragma GCC system_header
|
|
|
|
#ifndef _LIBCXX_MEMORY
|
|
#define _LIBCXX_MEMORY
|
|
|
|
#include <__config>
|
|
#include <cstddef>
|
|
#include <new>
|
|
#include <type_traits>
|
|
#include <utility>
|
|
|
|
_LIBCXX_BEGIN_NAMESPACE_STD
|
|
|
|
template <typename T>
|
|
class unique_ptr {
|
|
public:
|
|
unique_ptr()
|
|
: m_data(nullptr)
|
|
{
|
|
}
|
|
|
|
unique_ptr(T* data)
|
|
: m_data(data)
|
|
{
|
|
}
|
|
|
|
unique_ptr(std::nullptr_t)
|
|
: m_data(nullptr)
|
|
{
|
|
}
|
|
|
|
unique_ptr& operator=(std::nullptr_t)
|
|
{
|
|
reset();
|
|
return *this;
|
|
}
|
|
|
|
unique_ptr(unique_ptr&& moving) noexcept
|
|
: m_data(nullptr)
|
|
{
|
|
moving.swap(*this);
|
|
}
|
|
|
|
unique_ptr& operator=(unique_ptr&& moving) noexcept
|
|
{
|
|
moving.swap(*this);
|
|
return *this;
|
|
}
|
|
|
|
template <typename U>
|
|
unique_ptr(unique_ptr<U>&& moving)
|
|
{
|
|
unique_ptr<T> tmp((T*)moving.release());
|
|
tmp.swap(*this);
|
|
}
|
|
|
|
template <typename U>
|
|
unique_ptr& operator=(unique_ptr<U>&& moving)
|
|
{
|
|
unique_ptr<T> tmp((T*)moving.release());
|
|
tmp.swap(*this);
|
|
return *this;
|
|
}
|
|
|
|
T* release() noexcept
|
|
{
|
|
T* result = m_data;
|
|
m_data = nullptr;
|
|
return result;
|
|
}
|
|
|
|
void swap(unique_ptr& src) noexcept
|
|
{
|
|
T* tmp_data = m_data;
|
|
m_data = src.m_data;
|
|
src.m_data = tmp_data;
|
|
}
|
|
|
|
void reset()
|
|
{
|
|
T* tmp = release();
|
|
delete tmp;
|
|
}
|
|
|
|
void reset(T* new_ptr)
|
|
{
|
|
T* tmp = release();
|
|
delete tmp;
|
|
m_data = new_ptr;
|
|
}
|
|
|
|
~unique_ptr()
|
|
{
|
|
delete m_data;
|
|
}
|
|
|
|
unique_ptr(unique_ptr const&) = delete;
|
|
unique_ptr& operator=(unique_ptr const&) = delete;
|
|
|
|
T* operator->() const { return m_data; }
|
|
T& operator*() const { return *m_data; }
|
|
|
|
T* get() const { return m_data; }
|
|
explicit operator bool() const { return m_data; }
|
|
|
|
private:
|
|
T* m_data { nullptr };
|
|
};
|
|
|
|
template <class Alloc>
|
|
struct allocator_traits {
|
|
using allocator_type = Alloc;
|
|
using value_type = typename Alloc::value_type;
|
|
using pointer = typename Alloc::pointer;
|
|
using const_pointer = typename Alloc::const_pointer;
|
|
using void_pointer = typename Alloc::void_pointer;
|
|
using const_void_pointer = typename Alloc::const_void_pointer;
|
|
using difference_type = typename Alloc::difference_type;
|
|
using size_type = typename Alloc::size_type;
|
|
};
|
|
|
|
template <class _Alloc, class S>
|
|
struct __rebind_alloc_helper;
|
|
|
|
template <template <class, class...> class _Alloc, class New, class Old, class... OtherArgs>
|
|
struct __rebind_alloc_helper<_Alloc<Old, OtherArgs...>, New> {
|
|
typedef typename std::allocator_traits<_Alloc<New, OtherArgs...>>::allocator_type type;
|
|
};
|
|
|
|
template <class T>
|
|
struct allocator {
|
|
using value_type = T;
|
|
using pointer = T*;
|
|
using const_pointer = const T*;
|
|
using void_pointer = void*;
|
|
using const_void_pointer = const void*;
|
|
using difference_type = ptrdiff_t;
|
|
using size_type = size_t;
|
|
|
|
allocator() = default;
|
|
~allocator() = default;
|
|
|
|
pointer allocate(size_t n)
|
|
{
|
|
return reinterpret_cast<pointer>(operator new(n * sizeof(T)));
|
|
}
|
|
|
|
void deallocate(pointer p, size_t n)
|
|
{
|
|
return operator delete(p, n);
|
|
}
|
|
};
|
|
|
|
template <class T, class... Args>
|
|
static constexpr unique_ptr<T> make_unique(Args&&... args)
|
|
{
|
|
return new T(forward<Args>(args)...);
|
|
}
|
|
|
|
template <class T, class... Args>
|
|
static constexpr T* construct_at(T* p, Args&&... args)
|
|
{
|
|
return reinterpret_cast<T*>(new (static_cast<void*>(p)) T(forward<Args>(args)...));
|
|
}
|
|
|
|
template <class T>
|
|
static constexpr void destroy_at(T* p)
|
|
{
|
|
if constexpr (is_array_v<T>) {
|
|
static_assert(true, "Not implemented destroy_at for arrays");
|
|
}
|
|
return p->~T();
|
|
}
|
|
|
|
#if defined(_LIBCXX_BUILD_XOS_EXTENSIONS)
|
|
_LIBCXX_BEGIN_XOS_EXTENSION
|
|
|
|
template <class T, class... Args>
|
|
static constexpr T& construct(Args&&... args)
|
|
{
|
|
T* newobject = new T(forward<Args>(args)...);
|
|
return *newobject;
|
|
}
|
|
|
|
_LIBCXX_END_XOS_EXTENSION
|
|
#endif
|
|
|
|
template <class T>
|
|
T* to_address(T* p)
|
|
{
|
|
static_assert(!is_function_v<T>);
|
|
return p;
|
|
}
|
|
|
|
template <class T>
|
|
T* to_address(const T& p)
|
|
{
|
|
return to_address(p.operator->());
|
|
}
|
|
|
|
_LIBCXX_END_NAMESPACE_STD
|
|
|
|
#endif // _LIBCXX_MEMORY |