additional lib for vulkan
This commit is contained in:
210
enginecustom/include/Vulkan/Include/slang/slang-com-ptr.h
Normal file
210
enginecustom/include/Vulkan/Include/slang/slang-com-ptr.h
Normal file
@@ -0,0 +1,210 @@
|
||||
#ifndef SLANG_COM_PTR_H
|
||||
#define SLANG_COM_PTR_H
|
||||
|
||||
#include "slang-com-helper.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <cstddef>
|
||||
|
||||
namespace Slang
|
||||
{
|
||||
|
||||
/*! \brief ComPtr is a simple smart pointer that manages types which implement COM based interfaces.
|
||||
\details A class that implements a COM, must derive from the IUnknown interface or a type that
|
||||
matches it's layout exactly (such as ISlangUnknown). Trying to use this template with a class that
|
||||
doesn't follow these rules, will lead to undefined behavior. This is a 'strong' pointer type, and
|
||||
will AddRef when a non null pointer is set and Release when the pointer leaves scope. Using 'detach'
|
||||
allows a pointer to be removed from the management of the ComPtr. To set the smart pointer to null,
|
||||
there is the method setNull, or alternatively just assign SLANG_NULL/nullptr.
|
||||
|
||||
One edge case using the template is that sometimes you want access as a pointer to a pointer.
|
||||
Sometimes this is to write into the smart pointer, other times to pass as an array. To handle these
|
||||
different behaviors there are the methods readRef and writeRef, which are used instead of the &
|
||||
(ref) operator. For example
|
||||
|
||||
\code
|
||||
Void doSomething(ID3D12Resource** resources, IndexT numResources);
|
||||
// ...
|
||||
ComPtr<ID3D12Resource> resources[3];
|
||||
doSomething(resources[0].readRef(), SLANG_COUNT_OF(resource));
|
||||
\endcode
|
||||
|
||||
A more common scenario writing to the pointer
|
||||
|
||||
\code
|
||||
IUnknown* unk = ...;
|
||||
|
||||
ComPtr<ID3D12Resource> resource;
|
||||
Result res = unk->QueryInterface(resource.writeRef());
|
||||
\endcode
|
||||
*/
|
||||
|
||||
// Enum to force initializing as an attach (without adding a reference)
|
||||
enum InitAttach
|
||||
{
|
||||
INIT_ATTACH
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class ComPtr
|
||||
{
|
||||
public:
|
||||
typedef T Type;
|
||||
typedef ComPtr ThisType;
|
||||
typedef ISlangUnknown* Ptr;
|
||||
|
||||
/// Constructors
|
||||
/// Default Ctor. Sets to nullptr
|
||||
SLANG_FORCE_INLINE ComPtr()
|
||||
: m_ptr(nullptr)
|
||||
{
|
||||
}
|
||||
SLANG_FORCE_INLINE ComPtr(std::nullptr_t)
|
||||
: m_ptr(nullptr)
|
||||
{
|
||||
}
|
||||
/// Sets, and ref counts.
|
||||
SLANG_FORCE_INLINE explicit ComPtr(T* ptr)
|
||||
: m_ptr(ptr)
|
||||
{
|
||||
if (ptr)
|
||||
((Ptr)ptr)->addRef();
|
||||
}
|
||||
/// The copy ctor
|
||||
SLANG_FORCE_INLINE ComPtr(const ThisType& rhs)
|
||||
: m_ptr(rhs.m_ptr)
|
||||
{
|
||||
if (m_ptr)
|
||||
((Ptr)m_ptr)->addRef();
|
||||
}
|
||||
|
||||
/// Ctor without adding to ref count.
|
||||
SLANG_FORCE_INLINE explicit ComPtr(InitAttach, T* ptr)
|
||||
: m_ptr(ptr)
|
||||
{
|
||||
}
|
||||
/// Ctor without adding to ref count
|
||||
SLANG_FORCE_INLINE ComPtr(InitAttach, const ThisType& rhs)
|
||||
: m_ptr(rhs.m_ptr)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef SLANG_HAS_MOVE_SEMANTICS
|
||||
/// Move Ctor
|
||||
SLANG_FORCE_INLINE ComPtr(ThisType&& rhs)
|
||||
: m_ptr(rhs.m_ptr)
|
||||
{
|
||||
rhs.m_ptr = nullptr;
|
||||
}
|
||||
/// Move assign
|
||||
SLANG_FORCE_INLINE ComPtr& operator=(ThisType&& rhs)
|
||||
{
|
||||
T* swap = m_ptr;
|
||||
m_ptr = rhs.m_ptr;
|
||||
rhs.m_ptr = swap;
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// Destructor releases the pointer, assuming it is set
|
||||
SLANG_FORCE_INLINE ~ComPtr()
|
||||
{
|
||||
if (m_ptr)
|
||||
((Ptr)m_ptr)->release();
|
||||
}
|
||||
|
||||
// !!! Operators !!!
|
||||
|
||||
/// Returns the dumb pointer
|
||||
SLANG_FORCE_INLINE operator T*() const { return m_ptr; }
|
||||
|
||||
SLANG_FORCE_INLINE T& operator*() { return *m_ptr; }
|
||||
/// For making method invocations through the smart pointer work through the dumb pointer
|
||||
SLANG_FORCE_INLINE T* operator->() const { return m_ptr; }
|
||||
|
||||
/// Assign
|
||||
SLANG_FORCE_INLINE const ThisType& operator=(const ThisType& rhs);
|
||||
/// Assign from dumb ptr
|
||||
SLANG_FORCE_INLINE T* operator=(T* in);
|
||||
|
||||
/// Get the pointer and don't ref
|
||||
SLANG_FORCE_INLINE T* get() const { return m_ptr; }
|
||||
/// Release a contained nullptr pointer if set
|
||||
SLANG_FORCE_INLINE void setNull();
|
||||
|
||||
/// Detach
|
||||
SLANG_FORCE_INLINE T* detach()
|
||||
{
|
||||
T* ptr = m_ptr;
|
||||
m_ptr = nullptr;
|
||||
return ptr;
|
||||
}
|
||||
/// Set to a pointer without changing the ref count
|
||||
SLANG_FORCE_INLINE void attach(T* in) { m_ptr = in; }
|
||||
|
||||
/// Get ready for writing (nulls contents)
|
||||
SLANG_FORCE_INLINE T** writeRef()
|
||||
{
|
||||
setNull();
|
||||
return &m_ptr;
|
||||
}
|
||||
/// Get for read access
|
||||
SLANG_FORCE_INLINE T* const* readRef() const { return &m_ptr; }
|
||||
|
||||
/// Swap
|
||||
void swap(ThisType& rhs);
|
||||
|
||||
protected:
|
||||
/// Gets the address of the dumb pointer.
|
||||
// Disabled: use writeRef and readRef to get a reference based on usage.
|
||||
#ifndef SLANG_COM_PTR_ENABLE_REF_OPERATOR
|
||||
SLANG_FORCE_INLINE T** operator&() = delete;
|
||||
#endif
|
||||
|
||||
T* m_ptr;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void ComPtr<T>::setNull()
|
||||
{
|
||||
if (m_ptr)
|
||||
{
|
||||
((Ptr)m_ptr)->release();
|
||||
m_ptr = nullptr;
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
const ComPtr<T>& ComPtr<T>::operator=(const ThisType& rhs)
|
||||
{
|
||||
if (rhs.m_ptr)
|
||||
((Ptr)rhs.m_ptr)->addRef();
|
||||
if (m_ptr)
|
||||
((Ptr)m_ptr)->release();
|
||||
m_ptr = rhs.m_ptr;
|
||||
return *this;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
T* ComPtr<T>::operator=(T* ptr)
|
||||
{
|
||||
if (ptr)
|
||||
((Ptr)ptr)->addRef();
|
||||
if (m_ptr)
|
||||
((Ptr)m_ptr)->release();
|
||||
m_ptr = ptr;
|
||||
return m_ptr;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
void ComPtr<T>::swap(ThisType& rhs)
|
||||
{
|
||||
T* tmp = m_ptr;
|
||||
m_ptr = rhs.m_ptr;
|
||||
rhs.m_ptr = tmp;
|
||||
}
|
||||
|
||||
} // namespace Slang
|
||||
|
||||
#endif // SLANG_COM_PTR_H
|
Reference in New Issue
Block a user