#ifndef WTF_PassRef_h
#define WTF_PassRef_h
#include "Assertions.h"
#include <cstddef>
#include <utility>
namespace WTF {
template<typename T> class PassRef;
template<typename T> class PassRefPtr;
template<typename T> class Ref;
template<typename T> class RefPtr;
template<typename T> PassRef<T> adoptRef(T&);
inline void adopted(const void*) { }
template<typename T> class PassRef {
public:
PassRef(T&);
PassRef(PassRef&&);
template<typename U> PassRef(PassRef<U>);
const T& get() const;
T& get();
void dropRef();
T& leakRef() WARN_UNUSED_RETURN;
#ifndef NDEBUG
~PassRef();
#endif
private:
friend PassRef adoptRef<T>(T&);
template<typename U> friend class PassRef;
template<typename U> friend class PassRefPtr;
template<typename U> friend class Ref;
template<typename U> friend class RefPtr;
enum AdoptTag { Adopt };
PassRef(T&, AdoptTag);
T& m_reference;
#ifndef NDEBUG
bool m_gaveUpReference;
#endif
};
template<typename T> inline PassRef<T>::PassRef(T& reference)
: m_reference(reference)
#ifndef NDEBUG
, m_gaveUpReference(false)
#endif
{
reference.ref();
}
template<typename T> inline PassRef<T>::PassRef(PassRef&& other)
: m_reference(other.leakRef())
#ifndef NDEBUG
, m_gaveUpReference(false)
#endif
{
}
template<typename T> template<typename U> inline PassRef<T>::PassRef(PassRef<U> other)
: m_reference(other.leakRef())
#ifndef NDEBUG
, m_gaveUpReference(false)
#endif
{
}
#ifndef NDEBUG
template<typename T> PassRef<T>::~PassRef()
{
ASSERT(m_gaveUpReference);
}
#endif
template<typename T> inline void PassRef<T>::dropRef()
{
ASSERT(!m_gaveUpReference);
m_reference.deref();
#ifndef NDEBUG
m_gaveUpReference = true;
#endif
}
template<typename T> inline const T& PassRef<T>::get() const
{
ASSERT(!m_gaveUpReference);
return m_reference;
}
template<typename T> inline T& PassRef<T>::get()
{
ASSERT(!m_gaveUpReference);
return m_reference;
}
template<typename T> inline T& PassRef<T>::leakRef()
{
#ifndef NDEBUG
ASSERT(!m_gaveUpReference);
m_gaveUpReference = true;
#endif
return m_reference;
}
template<typename T> inline PassRef<T>::PassRef(T& reference, AdoptTag)
: m_reference(reference)
#ifndef NDEBUG
, m_gaveUpReference(false)
#endif
{
}
template<typename T> inline PassRef<T> adoptRef(T& reference)
{
adopted(&reference);
return PassRef<T>(reference, PassRef<T>::Adopt);
}
template<typename T, typename... Args> inline PassRef<T> createRefCounted(Args&&... args)
{
return adoptRef(*new T(std::forward<Args>(args)...));
}
}
using WTF::PassRef;
using WTF::adoptRef;
using WTF::createRefCounted;
#endif // WTF_PassRef_h