Files
moslab-code/src/l4/pkg/l4re-core/cxx/lib/tl/include/unique_ptr
2025-09-12 15:55:45 +02:00

128 lines
2.6 KiB
C++

// vi:set ft=cpp: -*- Mode: C++ -*-
/*
* Copyright (C) 2013 Technische Universität Dresden.
* Copyright (C) 2014-2017, 2020, 2023-2024 Kernkonzept GmbH.
*
* License: see LICENSE.spdx (in this directory or the directories above)
*/
#pragma once
#include "type_traits"
namespace cxx
{
template< typename T >
struct default_delete
{
default_delete() {}
template< typename U >
default_delete(default_delete<U> const &) {}
void operator () (T *p) const
{ delete p; }
};
template< typename T >
struct default_delete<T[]>
{
default_delete() {}
void operator () (T *p)
{ delete [] p; }
};
template< typename T, typename C >
struct unique_ptr_index_op {};
template< typename T, typename C >
struct unique_ptr_index_op<T[], C>
{
typedef T &reference;
reference operator [] (int idx) const
{ return static_cast<C const *>(this)->get()[idx]; }
};
template< typename T, typename T_Del = default_delete<T> >
class unique_ptr : public unique_ptr_index_op<T, unique_ptr<T, T_Del> >
{
private:
struct _unspec;
typedef _unspec* _unspec_ptr_type;
public:
typedef cxx::remove_extent_t<T> element_type;
typedef element_type *pointer;
typedef element_type &reference;
typedef T_Del deleter_type;
unique_ptr() : _ptr(pointer()) {}
explicit unique_ptr(pointer p) : _ptr(p) {}
unique_ptr(unique_ptr &&o) : _ptr(o.release()) {}
~unique_ptr() { reset(); }
unique_ptr &operator = (unique_ptr &&o)
{
reset(o.release());
return *this;
}
unique_ptr &operator = (_unspec_ptr_type)
{
reset();
return *this;
}
element_type &operator * () const { return *get(); }
pointer operator -> () const { return get(); }
pointer get() const { return _ptr; }
operator _unspec_ptr_type () const
{ return reinterpret_cast<_unspec_ptr_type>(get()); }
pointer release()
{
pointer r = _ptr;
_ptr = 0;
return r;
}
void reset(pointer p = pointer())
{
if (p != get())
{
deleter_type()(get());
_ptr = p;
}
}
unique_ptr(unique_ptr const &) = delete;
unique_ptr &operator = (unique_ptr const &) = delete;
private:
pointer _ptr;
};
template< typename T >
unique_ptr<T>
make_unique_ptr(T *p)
{ return unique_ptr<T>(p); }
template< typename T >
cxx::enable_if_t<cxx::is_array<T>::value, unique_ptr<T>>
make_unique(unsigned long size)
{ return cxx::unique_ptr<T>(new cxx::remove_extent_t<T>[size]()); }
template< typename T, typename... Args >
cxx::enable_if_t<!cxx::is_array<T>::value, unique_ptr<T>>
make_unique(Args &&... args)
{ return cxx::unique_ptr<T>(new T(cxx::forward<Args>(args)...)); }
}