#ifndef RefCounter_h
#define RefCounter_h
#include <functional>
#include <wtf/Noncopyable.h>
#include <wtf/RefPtr.h>
namespace WTF {
class RefCounter {
WTF_MAKE_NONCOPYABLE(RefCounter);
class Count {
WTF_MAKE_NONCOPYABLE(Count);
public:
WTF_EXPORT_PRIVATE void ref();
WTF_EXPORT_PRIVATE void deref();
private:
friend class RefCounter;
Count(RefCounter& refCounter)
: m_refCounter(&refCounter)
, m_value(0)
{
}
RefCounter* m_refCounter;
unsigned m_value;
};
public:
template<typename T>
class Token {
public:
Token() { }
Token(std::nullptr_t) { }
inline Token(const Token<T>&);
inline Token(Token<T>&&);
inline Token<T>& operator=(std::nullptr_t);
inline Token<T>& operator=(const Token<T>&);
inline Token<T>& operator=(Token<T>&&);
explicit operator bool() const { return m_ptr; }
private:
friend class RefCounter;
inline Token(Count* count);
RefPtr<Count> m_ptr;
};
WTF_EXPORT_PRIVATE RefCounter(std::function<void(bool)> = [](bool) { });
WTF_EXPORT_PRIVATE ~RefCounter();
template<typename T>
Token<T> token() const
{
return Token<T>(m_count);
}
unsigned value() const
{
return m_count->m_value;
}
private:
std::function<void(bool)> m_valueDidChange;
Count* m_count;
};
template<class T>
inline RefCounter::Token<T>::Token(Count* count)
: m_ptr(count)
{
}
template<class T>
inline RefCounter::Token<T>::Token(const RefCounter::Token<T>& token)
: m_ptr(token.m_ptr)
{
}
template<class T>
inline RefCounter::Token<T>::Token(RefCounter::Token<T>&& token)
: m_ptr(token.m_ptr)
{
}
template<class T>
inline RefCounter::Token<T>& RefCounter::Token<T>::operator=(std::nullptr_t)
{
m_ptr = nullptr;
return *this;
}
template<class T>
inline RefCounter::Token<T>& RefCounter::Token<T>::operator=(const RefCounter::Token<T>& token)
{
m_ptr = token.m_ptr;
return *this;
}
template<class T>
inline RefCounter::Token<T>& RefCounter::Token<T>::operator=(RefCounter::Token<T>&& token)
{
m_ptr = token.m_ptr;
return *this;
}
}
using WTF::RefCounter;
#endif // RefCounter_h