大改
This commit is contained in:
226
csgo2/LuaBridge/luaBridge/RefCountedPtr.h
Normal file
226
csgo2/LuaBridge/luaBridge/RefCountedPtr.h
Normal file
@@ -0,0 +1,226 @@
|
||||
// https://github.com/vinniefalco/LuaBridge
|
||||
// Copyright 2021, Stefan Frings
|
||||
// Copyright 2019, Dmitry Tarakanov
|
||||
// Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
// Copyright 2007, Nathan Reed
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
|
||||
namespace luabridge {
|
||||
|
||||
namespace detail {
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Support for our RefCountedPtr.
|
||||
*/
|
||||
struct RefCountedPtrBase
|
||||
{
|
||||
// Declaration of container for the refcounts
|
||||
typedef std::unordered_map<const void*, int> RefCountsType;
|
||||
|
||||
protected:
|
||||
RefCountsType& getRefCounts() const
|
||||
{
|
||||
static RefCountsType refcounts;
|
||||
return refcounts;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A reference counted smart pointer.
|
||||
|
||||
The api is compatible with boost::RefCountedPtr and std::RefCountedPtr, in the
|
||||
sense that it implements a strict subset of the functionality.
|
||||
|
||||
This implementation uses a hash table to look up the reference count
|
||||
associated with a particular pointer.
|
||||
|
||||
@tparam T The class type.
|
||||
|
||||
@todo Decompose RefCountedPtr using a policy. At a minimum, the underlying
|
||||
reference count should be policy based (to support atomic operations)
|
||||
and the delete behavior should be policy based (to support custom
|
||||
disposal methods).
|
||||
|
||||
@todo Provide an intrusive version of RefCountedPtr.
|
||||
*/
|
||||
template<class T>
|
||||
class RefCountedPtr : private detail::RefCountedPtrBase
|
||||
{
|
||||
public:
|
||||
template<typename Other>
|
||||
struct rebind
|
||||
{
|
||||
typedef RefCountedPtr<Other> other;
|
||||
};
|
||||
|
||||
/** Construct as nullptr or from existing pointer to T.
|
||||
|
||||
@param p The optional, existing pointer to assign from.
|
||||
*/
|
||||
RefCountedPtr(T* const p = nullptr) : m_p(p)
|
||||
{
|
||||
if (m_p)
|
||||
{
|
||||
++getRefCounts()[m_p];
|
||||
}
|
||||
}
|
||||
|
||||
/** Construct from another RefCountedPtr.
|
||||
|
||||
@param rhs The RefCountedPtr to assign from.
|
||||
*/
|
||||
RefCountedPtr(RefCountedPtr<T> const& rhs) : RefCountedPtr(rhs.get()) {}
|
||||
|
||||
/** Construct from a RefCountedPtr of a different type.
|
||||
|
||||
@invariant A pointer to U must be convertible to a pointer to T.
|
||||
|
||||
@tparam U The other object type.
|
||||
@param rhs The RefCountedPtr to assign from.
|
||||
*/
|
||||
template<typename U>
|
||||
RefCountedPtr(RefCountedPtr<U> const& rhs) : RefCountedPtr(rhs.get())
|
||||
{
|
||||
}
|
||||
|
||||
/** Release the object.
|
||||
|
||||
If there are no more references then the object is deleted.
|
||||
*/
|
||||
~RefCountedPtr() { reset(); }
|
||||
|
||||
/** Assign from another RefCountedPtr.
|
||||
|
||||
@param rhs The RefCountedPtr to assign from.
|
||||
@returns A reference to the RefCountedPtr.
|
||||
*/
|
||||
RefCountedPtr<T>& operator=(RefCountedPtr<T> const& rhs)
|
||||
{
|
||||
// NOTE Self assignment is handled gracefully
|
||||
*this = rhs.get();
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Assign from another RefCountedPtr of a different type.
|
||||
|
||||
@note A pointer to U must be convertible to a pointer to T.
|
||||
|
||||
@tparam U The other object type.
|
||||
@param rhs The other RefCountedPtr to assign from.
|
||||
@returns A reference to the RefCountedPtr.
|
||||
*/
|
||||
template<typename U>
|
||||
RefCountedPtr<T>& operator=(RefCountedPtr<U> const& rhs)
|
||||
{
|
||||
// NOTE Self assignment is handled gracefully
|
||||
*this = rhs.get();
|
||||
return *this;
|
||||
}
|
||||
|
||||
RefCountedPtr<T>& operator=(T* const p)
|
||||
{
|
||||
if (p != m_p)
|
||||
{
|
||||
RefCountedPtr<T> tmp(p);
|
||||
std::swap(m_p, tmp.m_p);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Retrieve the raw pointer.
|
||||
|
||||
@returns A pointer to the object.
|
||||
*/
|
||||
T* get() const { return m_p; }
|
||||
|
||||
/** Retrieve the raw pointer by conversion.
|
||||
|
||||
@returns A pointer to the object.
|
||||
*/
|
||||
operator T*() const { return m_p; }
|
||||
|
||||
/** Retrieve the raw pointer.
|
||||
|
||||
@returns A pointer to the object.
|
||||
*/
|
||||
T* operator*() const { return m_p; }
|
||||
|
||||
/** Retrieve the raw pointer.
|
||||
|
||||
@returns A pointer to the object.
|
||||
*/
|
||||
T* operator->() const { return m_p; }
|
||||
|
||||
/** Determine the number of references.
|
||||
|
||||
@note This is not thread-safe.
|
||||
|
||||
@returns The number of active references.
|
||||
*/
|
||||
RefCountsType::mapped_type use_count() const
|
||||
{
|
||||
if (!m_p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const auto itCounter = getRefCounts().find(m_p);
|
||||
assert(itCounter != getRefCounts().end());
|
||||
assert(itCounter->second > 0);
|
||||
|
||||
return itCounter->second;
|
||||
}
|
||||
|
||||
/** Release the pointer.
|
||||
|
||||
The reference count is decremented. If the reference count reaches
|
||||
zero, the object is deleted.
|
||||
*/
|
||||
void reset()
|
||||
{
|
||||
if (m_p)
|
||||
{
|
||||
const auto itCounter = getRefCounts().find(m_p);
|
||||
assert(itCounter != getRefCounts().end());
|
||||
assert(itCounter->second > 0);
|
||||
|
||||
if (--itCounter->second == 0)
|
||||
{
|
||||
delete m_p;
|
||||
getRefCounts().erase(itCounter);
|
||||
}
|
||||
|
||||
m_p = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
T* m_p;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
|
||||
// forward declaration
|
||||
template<class T>
|
||||
struct ContainerTraits;
|
||||
|
||||
template<class T>
|
||||
struct ContainerTraits<RefCountedPtr<T>>
|
||||
{
|
||||
typedef T Type;
|
||||
|
||||
static T* get(RefCountedPtr<T> const& c) { return c.get(); }
|
||||
};
|
||||
|
||||
} // namespace luabridge
|
||||
Reference in New Issue
Block a user