#pragma once
#include <wtf/DumbPtrTraits.h>
#include <wtf/FastMalloc.h>
namespace WTF {
template <typename T> class NakedRef {
WTF_MAKE_FAST_ALLOCATED;
public:
ALWAYS_INLINE NakedRef(T& ref) : m_ptr(&ref) { }
ALWAYS_INLINE NakedRef(const NakedRef&) = delete;
template<typename U> NakedRef(const NakedRef<U>&) = delete;
ALWAYS_INLINE NakedRef(NakedRef&& other)
: m_ptr(&other.leakRef())
{
ASSERT(m_ptr);
}
template<typename U>
NakedRef(NakedRef<U>&& other)
: m_ptr(&other.leakRef())
{
ASSERT(m_ptr);
}
ALWAYS_INLINE T* operator->() const { ASSERT(m_ptr); return m_ptr; }
T* ptr() const RETURNS_NONNULL { ASSERT(m_ptr); return m_ptr; }
T& get() const { return *m_ptr; }
operator T&() const { ASSERT(m_ptr); return *m_ptr; }
bool operator!() const { ASSERT(m_ptr); return !*m_ptr; }
NakedRef copyRef() && = delete;
NakedRef copyRef() const & WARN_UNUSED_RETURN { return NakedRef(*m_ptr); }
NakedRef& operator=(T&);
NakedRef& operator=(NakedRef&&);
template<typename U> NakedRef& operator=(NakedRef<U>&&);
NakedRef& operator=(const NakedRef&) = delete;
template<typename X> NakedRef& operator=(const NakedRef<X>&) = delete;
template<typename U> void swap(NakedRef<U>&);
T& leakRef() WARN_UNUSED_RETURN
{
ASSERT(m_ptr);
T& result = *DumbPtrTraits<T>::exchange(m_ptr, nullptr);
return result;
}
private:
T* m_ptr;
};
template<typename T> inline NakedRef<T>& NakedRef<T>::operator=(NakedRef&& reference)
{
NakedRef movedReference = WTFMove(reference);
swap(movedReference);
return *this;
}
template<typename T> inline NakedRef<T>& NakedRef<T>::operator=(T& ref)
{
NakedRef copiedReference = ref;
swap(copiedReference);
return *this;
}
template<typename T> template<typename U> inline NakedRef<T>& NakedRef<T>::operator=(NakedRef<U>&& other)
{
NakedRef ref = WTFMove(other);
swap(ref);
return *this;
}
template<class T>
template<class U>
inline void NakedRef<T>::swap(NakedRef<U>& other)
{
std::swap(m_ptr, other.m_ptr);
}
template<class T, class U> inline void swap(NakedRef<T>& a, NakedRef<U>& b)
{
a.swap(b);
}
}
using WTF::NakedRef;