2020-01-18 09:38:21 +01:00
/*
* Copyright ( c ) 2018 - 2020 , Andreas Kling < kling @ serenityos . org >
*
2021-04-22 01:24:48 -07:00
* SPDX - License - Identifier : BSD - 2 - Clause
2020-01-18 09:38:21 +01:00
*/
2018-10-10 11:53:07 +02:00
# pragma once
2019-07-24 08:25:27 +02:00
# include <AK/NonnullOwnPtr.h>
2020-06-12 16:30:30 +03:00
# include <AK/RefCounted.h>
2021-08-15 08:37:33 +00:00
# ifdef KERNEL
2021-09-04 21:04:10 +00:00
# include <Kernel / API / KResult.h>
2021-08-15 08:37:33 +00:00
# endif
2018-10-10 11:53:07 +02:00
2021-10-07 20:10:56 +01:00
# define OWNPTR_SCRUB_BYTE 0xf0
2018-10-10 11:53:07 +02:00
namespace AK {
template < typename T >
class OwnPtr {
public :
2021-01-10 16:29:28 -07:00
OwnPtr ( ) = default ;
2021-05-30 21:09:23 +04:30
OwnPtr ( decltype ( nullptr ) )
: m_ptr ( nullptr )
2019-05-28 11:53:16 +02:00
{
}
2021-05-30 21:09:23 +04:30
2019-05-28 11:53:16 +02:00
OwnPtr ( OwnPtr & & other )
: m_ptr ( other . leak_ptr ( ) )
{
}
2019-07-24 08:25:27 +02:00
template < typename U >
OwnPtr ( NonnullOwnPtr < U > & & other )
2020-04-05 11:32:30 +02:00
: m_ptr ( other . leak_ptr ( ) )
2019-07-24 08:25:27 +02:00
{
}
2019-05-28 11:53:16 +02:00
template < typename U >
OwnPtr ( OwnPtr < U > & & other )
2020-04-05 11:32:30 +02:00
: m_ptr ( other . leak_ptr ( ) )
2019-05-28 11:53:16 +02:00
{
}
2018-10-16 12:20:51 +02:00
~ OwnPtr ( )
{
clear ( ) ;
# ifdef SANITIZE_PTRS
2021-10-07 20:10:56 +01:00
m_ptr = ( T * ) ( explode_byte ( OWNPTR_SCRUB_BYTE ) ) ;
2018-10-16 12:20:51 +02:00
# endif
}
2018-10-10 11:53:07 +02:00
2019-07-24 08:25:27 +02:00
OwnPtr ( const OwnPtr & ) = delete ;
template < typename U >
OwnPtr ( const OwnPtr < U > & ) = delete ;
OwnPtr & operator = ( const OwnPtr & ) = delete ;
template < typename U >
OwnPtr & operator = ( const OwnPtr < U > & ) = delete ;
2019-08-01 15:46:18 +02:00
template < typename U >
OwnPtr ( const NonnullOwnPtr < U > & ) = delete ;
template < typename U >
OwnPtr & operator = ( const NonnullOwnPtr < U > & ) = delete ;
2019-07-11 16:43:20 +02:00
template < typename U >
OwnPtr ( const RefPtr < U > & ) = delete ;
template < typename U >
OwnPtr ( const NonnullRefPtr < U > & ) = delete ;
template < typename U >
OwnPtr ( const WeakPtr < U > & ) = delete ;
template < typename U >
OwnPtr & operator = ( const RefPtr < U > & ) = delete ;
template < typename U >
OwnPtr & operator = ( const NonnullRefPtr < U > & ) = delete ;
template < typename U >
OwnPtr & operator = ( const WeakPtr < U > & ) = delete ;
2018-10-10 11:53:07 +02:00
OwnPtr & operator = ( OwnPtr & & other )
{
2020-01-24 09:31:14 +01:00
OwnPtr ptr ( move ( other ) ) ;
swap ( ptr ) ;
2018-10-10 11:53:07 +02:00
return * this ;
}
template < typename U >
OwnPtr & operator = ( OwnPtr < U > & & other )
{
2020-01-24 09:31:14 +01:00
OwnPtr ptr ( move ( other ) ) ;
swap ( ptr ) ;
2018-10-10 11:53:07 +02:00
return * this ;
}
2019-07-24 08:25:27 +02:00
template < typename U >
OwnPtr & operator = ( NonnullOwnPtr < U > & & other )
{
2020-01-24 09:31:14 +01:00
OwnPtr ptr ( move ( other ) ) ;
swap ( ptr ) ;
2021-02-23 20:42:32 +01:00
VERIFY ( m_ptr ) ;
2019-07-24 08:25:27 +02:00
return * this ;
}
2021-05-30 21:09:23 +04:30
OwnPtr & operator = ( T * ptr ) = delete ;
2018-10-10 11:53:07 +02:00
OwnPtr & operator = ( std : : nullptr_t )
{
clear ( ) ;
return * this ;
}
void clear ( )
{
delete m_ptr ;
m_ptr = nullptr ;
}
bool operator ! ( ) const { return ! m_ptr ; }
2020-08-05 06:40:03 -07:00
[ [ nodiscard ] ] T * leak_ptr ( )
2018-10-10 11:53:07 +02:00
{
2019-07-24 08:25:27 +02:00
T * leaked_ptr = m_ptr ;
2018-10-10 11:53:07 +02:00
m_ptr = nullptr ;
2019-07-24 08:25:27 +02:00
return leaked_ptr ;
2018-10-10 11:53:07 +02:00
}
2019-08-14 11:02:49 +02:00
NonnullOwnPtr < T > release_nonnull ( )
{
2021-02-23 20:42:32 +01:00
VERIFY ( m_ptr ) ;
2019-08-14 11:02:49 +02:00
return NonnullOwnPtr < T > ( NonnullOwnPtr < T > : : Adopt , * leak_ptr ( ) ) ;
}
2020-04-05 11:32:30 +02:00
template < typename U >
NonnullOwnPtr < U > release_nonnull ( )
{
2021-02-23 20:42:32 +01:00
VERIFY ( m_ptr ) ;
2020-04-05 11:32:30 +02:00
return NonnullOwnPtr < U > ( NonnullOwnPtr < U > : : Adopt , static_cast < U & > ( * leak_ptr ( ) ) ) ;
}
2018-10-10 11:53:07 +02:00
T * ptr ( ) { return m_ptr ; }
const T * ptr ( ) const { return m_ptr ; }
2019-08-02 10:34:40 +02:00
T * operator - > ( )
{
2021-02-23 20:42:32 +01:00
VERIFY ( m_ptr ) ;
2019-08-02 10:34:40 +02:00
return m_ptr ;
}
const T * operator - > ( ) const
{
2021-02-23 20:42:32 +01:00
VERIFY ( m_ptr ) ;
2019-08-02 10:34:40 +02:00
return m_ptr ;
}
2018-10-10 11:53:07 +02:00
2019-08-02 10:34:40 +02:00
T & operator * ( )
{
2021-02-23 20:42:32 +01:00
VERIFY ( m_ptr ) ;
2019-08-02 10:34:40 +02:00
return * m_ptr ;
}
const T & operator * ( ) const
{
2021-02-23 20:42:32 +01:00
VERIFY ( m_ptr ) ;
2019-08-02 10:34:40 +02:00
return * m_ptr ;
}
2018-10-10 11:53:07 +02:00
2019-04-14 02:36:06 +02:00
operator const T * ( ) const { return m_ptr ; }
operator T * ( ) { return m_ptr ; }
2018-10-10 11:53:07 +02:00
operator bool ( ) { return ! ! m_ptr ; }
2020-01-24 09:31:14 +01:00
void swap ( OwnPtr & other )
{
: : swap ( m_ptr , other . m_ptr ) ;
}
template < typename U >
void swap ( OwnPtr < U > & other )
{
: : swap ( m_ptr , other . m_ptr ) ;
}
2021-05-30 21:09:23 +04:30
static OwnPtr lift ( T * ptr )
{
return OwnPtr { ptr } ;
}
protected :
explicit OwnPtr ( T * ptr )
: m_ptr ( ptr )
{
static_assert (
2021-06-25 07:33:15 +02:00
requires { requires typename T : : AllowOwnPtr ( ) ( ) ; } | | ! requires { requires ! typename T : : AllowOwnPtr ( ) ( ) ; declval < T > ( ) . ref ( ) ; declval < T > ( ) . unref ( ) ; } , " Use RefPtr<> for RefCounted types " ) ;
2021-05-30 21:09:23 +04:30
}
2018-10-10 11:53:07 +02:00
private :
T * m_ptr = nullptr ;
} ;
2020-01-24 09:31:14 +01:00
template < typename T , typename U >
inline void swap ( OwnPtr < T > & a , OwnPtr < U > & b )
{
a . swap ( b ) ;
}
2021-05-12 20:35:08 -07:00
template < typename T >
inline OwnPtr < T > adopt_own_if_nonnull ( T * object )
{
if ( object )
2021-05-30 21:09:23 +04:30
return OwnPtr < T > : : lift ( object ) ;
2021-05-12 20:35:08 -07:00
return { } ;
}
2021-08-15 08:37:33 +00:00
# ifdef KERNEL
template < typename T >
inline Kernel : : KResultOr < NonnullOwnPtr < T > > adopt_nonnull_own_or_enomem ( T * object )
{
auto result = adopt_own_if_nonnull ( object ) ;
if ( ! result )
return ENOMEM ;
return result . release_nonnull ( ) ;
}
# endif
2021-06-20 10:04:41 +02:00
template < typename T , class . . . Args >
2021-07-01 10:21:14 +02:00
requires ( IsConstructible < T , Args . . . > ) inline OwnPtr < T > try_make ( Args & & . . . args )
2021-06-20 10:04:41 +02:00
{
return adopt_own_if_nonnull ( new ( nothrow ) T ( forward < Args > ( args ) . . . ) ) ;
}
2021-07-01 10:21:14 +02:00
// FIXME: Remove once P0960R3 is available in Clang.
template < typename T , class . . . Args >
inline OwnPtr < T > try_make ( Args & & . . . args )
{
return adopt_own_if_nonnull ( new ( nothrow ) T { forward < Args > ( args ) . . . } ) ;
}
2018-10-26 17:42:12 +02:00
template < typename T >
2019-06-29 19:14:03 +02:00
struct Traits < OwnPtr < T > > : public GenericTraits < OwnPtr < T > > {
2021-05-08 12:11:37 +03:00
using PeekType = T * ;
using ConstPeekType = const T * ;
2020-02-17 13:19:28 -06:00
static unsigned hash ( const OwnPtr < T > & p ) { return ptr_hash ( p . ptr ( ) ) ; }
2019-06-29 19:14:03 +02:00
static bool equals ( const OwnPtr < T > & a , const OwnPtr < T > & b ) { return a . ptr ( ) = = b . ptr ( ) ; }
2018-10-26 17:42:12 +02:00
} ;
2018-10-10 11:53:07 +02:00
}
2021-05-12 20:35:08 -07:00
using AK : : adopt_own_if_nonnull ;
2019-05-28 11:53:16 +02:00
using AK : : OwnPtr ;
2021-06-20 10:04:41 +02:00
using AK : : try_make ;
2021-08-15 08:37:33 +00:00
# ifdef KERNEL
using AK : : adopt_nonnull_own_or_enomem ;
# endif