common: merge dup_handle and handle and use traits
Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
parent
96ae46eaa9
commit
bf4dd4a1d0
@ -12,41 +12,37 @@
|
|||||||
|
|
||||||
namespace macstd {
|
namespace macstd {
|
||||||
///
|
///
|
||||||
/// IOKit handle wrapper class
|
/// Core Foundation object traits
|
||||||
///
|
///
|
||||||
template <typename T, const T INVAL>
|
template <typename T>
|
||||||
class cf_object : public handle<T, INVAL>
|
struct cfobject_traits
|
||||||
{
|
{
|
||||||
MACSTD_HANDLE_IMPL(cf_object, T, INVAL)
|
static inline constexpr T invalid = static_cast<T>(NULL);
|
||||||
|
|
||||||
public:
|
|
||||||
///
|
///
|
||||||
/// Releases a Core Foundation object
|
/// Releases a Core Foundation object
|
||||||
///
|
///
|
||||||
/// \sa [CFRelease function](https://developer.apple.com/documentation/corefoundation/1521153-cfrelease)
|
/// \sa [CFRelease function](https://developer.apple.com/documentation/corefoundation/1521153-cfrelease)
|
||||||
///
|
///
|
||||||
virtual ~cf_object()
|
static void free(T h)
|
||||||
{
|
{
|
||||||
if (this->m_h != INVAL)
|
CFRelease(h);
|
||||||
free_internal();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
///
|
static T duplicate(T h);
|
||||||
/// Releases a Core Foundation object
|
|
||||||
///
|
|
||||||
/// \sa [CFRelease function](https://developer.apple.com/documentation/corefoundation/1521153-cfrelease)
|
|
||||||
///
|
|
||||||
void free_internal() noexcept override
|
|
||||||
{
|
|
||||||
CFRelease(this->m_h);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using cfarray = cf_object<CFArrayRef, static_cast<CFArrayRef>(NULL)>;
|
///
|
||||||
using cfdictionary = cf_object<CFDictionaryRef, static_cast<CFDictionaryRef>(NULL)>;
|
/// Core Foundation object traits
|
||||||
using cferror = cf_object<CFErrorRef, static_cast<CFErrorRef>(NULL)>;
|
///
|
||||||
using cfstring = cf_object<CFStringRef, static_cast<CFStringRef>(NULL)>;
|
template <typename T>
|
||||||
|
using cfobject = handle<T, cfobject_traits<T>>;
|
||||||
|
|
||||||
|
using cfarray = cfobject<CFArrayRef>;
|
||||||
|
using cfdictionary = cfobject<CFDictionaryRef>;
|
||||||
|
using cferror = cfobject<CFErrorRef>;
|
||||||
|
using cfstring = cfobject<CFStringRef>;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Core Foundation runtime error
|
/// Core Foundation runtime error
|
||||||
|
@ -6,41 +6,37 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
#import <IOKit/IOKitLib.h>
|
#include <IOKit/IOKitLib.h>
|
||||||
|
|
||||||
namespace macstd {
|
namespace macstd {
|
||||||
///
|
///
|
||||||
/// IOKit handle wrapper class
|
/// IOKit handle traits
|
||||||
///
|
///
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class io_object : public handle<T, 0>
|
struct io_object_traits
|
||||||
{
|
{
|
||||||
MACSTD_HANDLE_IMPL(io_object, T, 0)
|
static inline constexpr T invalid = 0;
|
||||||
|
|
||||||
public:
|
|
||||||
///
|
///
|
||||||
/// Releases an object handle
|
/// Releases an object handle
|
||||||
///
|
///
|
||||||
/// \sa [IOObjectRelease function](https://developer.apple.com/documentation/iokit/1514627-ioobjectrelease)
|
/// \sa [IOObjectRelease function](https://developer.apple.com/documentation/iokit/1514627-ioobjectrelease)
|
||||||
///
|
///
|
||||||
virtual ~io_object()
|
static void free(T h) noexcept
|
||||||
{
|
{
|
||||||
if (this->m_h != 0)
|
IOObjectRelease(h);
|
||||||
free_internal();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
///
|
static T duplicate(T h);
|
||||||
/// Releases an object handle
|
|
||||||
///
|
|
||||||
/// \sa [IOObjectRelease function](https://developer.apple.com/documentation/iokit/1514627-ioobjectrelease)
|
|
||||||
///
|
|
||||||
void free_internal() noexcept override
|
|
||||||
{
|
|
||||||
IOObjectRelease(this->m_h);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
/// IOKit handle traits
|
||||||
|
///
|
||||||
|
template <typename T>
|
||||||
|
using io_object = handle<T, io_object_traits<T>>;
|
||||||
|
|
||||||
using io_connect = io_object<io_connect_t>;
|
using io_connect = io_object<io_connect_t>;
|
||||||
using io_enumerator = io_object<io_enumerator_t>;
|
using io_enumerator = io_object<io_enumerator_t>;
|
||||||
using io_ident = io_object<io_ident_t>;
|
using io_ident = io_object<io_ident_t>;
|
||||||
|
@ -73,13 +73,32 @@ namespace macstd
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Authorization traits
|
||||||
|
///
|
||||||
|
struct authorization_traits
|
||||||
|
{
|
||||||
|
static inline constexpr AuthorizationRef invalid = static_cast<AuthorizationRef>(NULL);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Releases an object handle
|
||||||
|
///
|
||||||
|
/// \sa [AuthorizationFree function](https://developer.apple.com/documentation/security/authorizationfree)
|
||||||
|
///
|
||||||
|
static void free(AuthorizationRef h) noexcept
|
||||||
|
{
|
||||||
|
AuthorizationFree(h, kAuthorizationFlagDefaults);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static AuthorizationRef duplicate(AuthorizationRef h);
|
||||||
|
};
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Authorization reference wrapper class
|
/// Authorization reference wrapper class
|
||||||
///
|
///
|
||||||
class authorization : public handle<AuthorizationRef, static_cast<AuthorizationRef>(NULL)>
|
class authorization : public handle<AuthorizationRef, authorization_traits>
|
||||||
{
|
{
|
||||||
MACSTD_HANDLE_IMPL(authorization, AuthorizationRef, static_cast<AuthorizationRef>(NULL))
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
///
|
///
|
||||||
/// Creates a new authorization reference and provides an option to authorize or preauthorize rights
|
/// Creates a new authorization reference and provides an option to authorize or preauthorize rights
|
||||||
@ -108,30 +127,8 @@ namespace macstd
|
|||||||
throw security_runtime_error(status, "AuthorizationCreateFromExternalForm failed");
|
throw security_runtime_error(status, "AuthorizationCreateFromExternalForm failed");
|
||||||
this->m_h = h;
|
this->m_h = h;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
|
||||||
/// Releases an object handle
|
|
||||||
///
|
|
||||||
/// \sa [AuthorizationFree function](https://developer.apple.com/documentation/security/authorizationfree)
|
|
||||||
///
|
|
||||||
virtual ~authorization()
|
|
||||||
{
|
|
||||||
if (this->m_h != static_cast<AuthorizationRef>(NULL))
|
|
||||||
free_internal();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
///
|
|
||||||
/// Releases an object handle
|
|
||||||
///
|
|
||||||
/// \sa [AuthorizationFree function](https://developer.apple.com/documentation/security/authorizationfree)
|
|
||||||
///
|
|
||||||
void free_internal() noexcept override
|
|
||||||
{
|
|
||||||
AuthorizationFree(this->m_h, kAuthorizationFlagDefaults);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using sec_keychain = cf_object<SecKeychainRef, static_cast<SecKeychainRef>(NULL)>;
|
using sec_keychain = cfobject<SecKeychainRef>;
|
||||||
using sec_certificate = cf_object<SecCertificateRef, static_cast<SecCertificateRef>(NULL)>;
|
using sec_certificate = cfobject<SecCertificateRef>;
|
||||||
}
|
}
|
||||||
|
@ -32,32 +32,6 @@ private: \
|
|||||||
///
|
///
|
||||||
#define MACSTD_STACK_BUFFER_BYTES 1024
|
#define MACSTD_STACK_BUFFER_BYTES 1024
|
||||||
|
|
||||||
///
|
|
||||||
/// Implements default constructors and operators to prevent their auto-generation by compiler.
|
|
||||||
///
|
|
||||||
#define MACSTD_HANDLE_IMPL(C, T, INVAL) \
|
|
||||||
public: \
|
|
||||||
C ( ) noexcept {} \
|
|
||||||
C (_In_opt_ T h) noexcept : handle<T, INVAL>( h ) {} \
|
|
||||||
C (_Inout_ C &&h) noexcept : handle<T, INVAL>(std::move(h)) {} \
|
|
||||||
C& operator=(_In_opt_ T h) noexcept { handle<T, INVAL>::operator=( h ); return *this; } \
|
|
||||||
C& operator=(_Inout_ C &&h) noexcept { handle<T, INVAL>::operator=(std::move(h)); return *this; } \
|
|
||||||
MACSTD_NONCOPYABLE(C)
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Implements default constructors and operators to prevent their auto-generation by compiler.
|
|
||||||
///
|
|
||||||
#define MACSTD_DPLHANDLE_IMPL(C, T, INVAL) \
|
|
||||||
public: \
|
|
||||||
C ( ) noexcept {} \
|
|
||||||
C (_In_opt_ T h) noexcept : dplhandle<T, INVAL>( h ) {} \
|
|
||||||
C (_In_ const C &h) noexcept : dplhandle<T, INVAL>(duplicate_internal(h.m_h)) {} \
|
|
||||||
C (_Inout_ C &&h) noexcept : dplhandle<T, INVAL>(std::move (h )) {} \
|
|
||||||
C& operator=(_In_opt_ T h) noexcept { dplhandle<T, INVAL>::operator=( h ); return *this; } \
|
|
||||||
C& operator=(_In_ const C &h) noexcept { dplhandle<T, INVAL>::operator=( h ); return *this; } \
|
|
||||||
C& operator=(_Inout_ C &&h) noexcept { dplhandle<T, INVAL>::operator=(std::move(h)); return *this; } \
|
|
||||||
private:
|
|
||||||
|
|
||||||
namespace macstd
|
namespace macstd
|
||||||
{
|
{
|
||||||
///
|
///
|
||||||
@ -65,14 +39,14 @@ namespace macstd
|
|||||||
///
|
///
|
||||||
/// It provides basic operators and methods common to all descendands of this class establishing a base to ease the replacement of native object handle type with classes in object-oriented approach.
|
/// It provides basic operators and methods common to all descendands of this class establishing a base to ease the replacement of native object handle type with classes in object-oriented approach.
|
||||||
///
|
///
|
||||||
template <class T, const T INVAL>
|
template <class T, class TR>
|
||||||
class handle
|
class handle
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
///
|
///
|
||||||
/// Initializes a new class instance with the object handle set to INVAL.
|
/// Initializes a new class instance with the object handle set to TR::invalid.
|
||||||
///
|
///
|
||||||
handle() noexcept : m_h(INVAL)
|
handle() noexcept : m_h(TR::invalid)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -83,49 +57,74 @@ namespace macstd
|
|||||||
handle(_In_opt_ T h) noexcept : m_h(h)
|
handle(_In_opt_ T h) noexcept : m_h(h)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Copy constructor
|
||||||
|
///
|
||||||
|
/// \param[in,out] h A reference of another object
|
||||||
|
///
|
||||||
|
handle(const handle<T, TR> &h) : m_h(TR::duplicate(h.m_h))
|
||||||
|
{}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Move constructor
|
/// Move constructor
|
||||||
///
|
///
|
||||||
/// \param[in,out] h A rvalue reference of another object
|
/// \param[in,out] h A rvalue reference of another object
|
||||||
///
|
///
|
||||||
handle(_Inout_ handle<T, INVAL> &&h) noexcept
|
handle(handle<T, TR> &&h) noexcept
|
||||||
{
|
{
|
||||||
// Transfer handle.
|
// Transfer handle.
|
||||||
m_h = h.m_h;
|
m_h = h.m_h;
|
||||||
h.m_h = INVAL;
|
h.m_h = TR::invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
// This class is noncopyable.
|
|
||||||
handle(_In_ const handle<T, INVAL> &h) noexcept {};
|
|
||||||
handle<T, INVAL>& operator=(_In_ const handle<T, INVAL> &h) noexcept {};
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
///
|
///
|
||||||
/// Attaches already available object handle.
|
/// Attaches already available object handle.
|
||||||
///
|
///
|
||||||
/// \param[in] h Object handle value
|
/// \param[in] h Object handle value
|
||||||
///
|
///
|
||||||
handle<T, INVAL>& operator=(_In_opt_ T h) noexcept
|
handle<T, TR>& operator=(_In_opt_ T h) noexcept
|
||||||
{
|
{
|
||||||
attach(h);
|
attach(h);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Duplicates the object.
|
||||||
|
///
|
||||||
|
/// \param[in] h Object
|
||||||
|
///
|
||||||
|
handle<T, TR>& operator=(const handle<T, TR> &h) noexcept
|
||||||
|
{
|
||||||
|
if (this != std::addressof(h)) {
|
||||||
|
if (h.m_h != TR::invalid) {
|
||||||
|
T h_new = TR::duplicate(h.m_h);
|
||||||
|
|
||||||
|
if (this->m_h != TR::invalid)
|
||||||
|
TR::free(this->m_h);
|
||||||
|
this->m_h = h_new;
|
||||||
|
} else {
|
||||||
|
if (this->m_h != TR::invalid)
|
||||||
|
TR::free(this->m_h);
|
||||||
|
this->m_h = TR::invalid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Move assignment
|
/// Move assignment
|
||||||
///
|
///
|
||||||
/// \param[inout] h A rvalue reference of another object
|
/// \param[in,out] h A rvalue reference of another object
|
||||||
///
|
///
|
||||||
#pragma warning(suppress: 26432) // Move constructor is also present, but not detected by code analysis somehow.
|
handle<T, TR>& operator=(handle<T, TR> &&h) noexcept
|
||||||
handle<T, INVAL>& operator=(_Inout_ handle<T, INVAL> &&h) noexcept
|
|
||||||
{
|
{
|
||||||
if (this != std::addressof(h)) {
|
if (this != std::addressof(h)) {
|
||||||
// Transfer handle.
|
// Transfer handle.
|
||||||
if (m_h != INVAL)
|
if (m_h != TR::invalid)
|
||||||
free_internal();
|
TR::free(this->m_h);
|
||||||
m_h = h.m_h;
|
m_h = h.m_h;
|
||||||
h.m_h = INVAL;
|
h.m_h = TR::invalid;
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -147,7 +146,7 @@ namespace macstd
|
|||||||
///
|
///
|
||||||
T*& operator*() const
|
T*& operator*() const
|
||||||
{
|
{
|
||||||
assert(m_h != INVAL);
|
assert(m_h != TR::invalid);
|
||||||
return *m_h;
|
return *m_h;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,7 +156,7 @@ namespace macstd
|
|||||||
///
|
///
|
||||||
T* operator&()
|
T* operator&()
|
||||||
{
|
{
|
||||||
assert(m_h == INVAL);
|
assert(m_h == TR::invalid);
|
||||||
return &m_h;
|
return &m_h;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,7 +167,7 @@ namespace macstd
|
|||||||
///
|
///
|
||||||
T operator->() const
|
T operator->() const
|
||||||
{
|
{
|
||||||
assert(m_h != INVAL);
|
assert(m_h != TR::invalid);
|
||||||
return m_h;
|
return m_h;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,7 +182,7 @@ namespace macstd
|
|||||||
///
|
///
|
||||||
bool valid() const
|
bool valid() const
|
||||||
{
|
{
|
||||||
return m_h != INVAL;
|
return m_h != TR::invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -264,20 +263,42 @@ namespace macstd
|
|||||||
return m_h == h;
|
return m_h == h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Duplicates and returns a new object handle.
|
||||||
|
///
|
||||||
|
/// \return Duplicated object handle
|
||||||
|
///
|
||||||
|
T duplicate() const
|
||||||
|
{
|
||||||
|
return this->m_h != TR::invalid ? TR::duplicate(this->m_h) : TR::invalid;
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Sets a new object handle for the class
|
/// Sets a new object handle for the class
|
||||||
///
|
///
|
||||||
/// When the current object handle of the class is non-INVAL, the object is destroyed first.
|
/// When the current object handle of the class is non-TR::invalid, the object is destroyed first.
|
||||||
///
|
///
|
||||||
/// \param[in] h New object handle
|
/// \param[in] h New object handle
|
||||||
///
|
///
|
||||||
void attach(_In_opt_ T h) noexcept
|
void attach(_In_opt_ T h) noexcept
|
||||||
{
|
{
|
||||||
if (m_h != INVAL)
|
if (m_h != TR::invalid)
|
||||||
free_internal();
|
TR::free(m_h);
|
||||||
m_h = h;
|
m_h = h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Duplicates an object handle and sets a new object handle.
|
||||||
|
///
|
||||||
|
/// \param[in] h Object handle of existing object
|
||||||
|
///
|
||||||
|
void attach_duplicated(_In_opt_ T h)
|
||||||
|
{
|
||||||
|
if (this->m_h != TR::invalid)
|
||||||
|
TR::free(this->m_h);
|
||||||
|
this->m_h = h != TR::invalid ? TR::duplicate(h) : TR::invalid;
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Dismisses the object handle from this class
|
/// Dismisses the object handle from this class
|
||||||
///
|
///
|
||||||
@ -286,7 +307,7 @@ namespace macstd
|
|||||||
T detach()
|
T detach()
|
||||||
{
|
{
|
||||||
T h = m_h;
|
T h = m_h;
|
||||||
m_h = INVAL;
|
m_h = TR::invalid;
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -295,143 +316,16 @@ namespace macstd
|
|||||||
///
|
///
|
||||||
void free()
|
void free()
|
||||||
{
|
{
|
||||||
if (m_h != INVAL) {
|
if (m_h != TR::invalid) {
|
||||||
free_internal();
|
TR::free(m_h);
|
||||||
m_h = INVAL;
|
m_h = TR::invalid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
|
||||||
///
|
|
||||||
/// Abstract member function that must be implemented by child classes to do the actual object destruction.
|
|
||||||
///
|
|
||||||
virtual void free_internal() noexcept = 0;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
T m_h; ///< Object handle
|
T m_h; ///< Object handle
|
||||||
};
|
};
|
||||||
|
|
||||||
///
|
|
||||||
/// Base abstract template class to support object handle keeping for objects that support trivial handle duplication
|
|
||||||
///
|
|
||||||
template <class T, T INVAL>
|
|
||||||
class dplhandle : public handle<T, INVAL>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
///
|
|
||||||
/// Initializes a new class instance with the object handle set to INVAL.
|
|
||||||
///
|
|
||||||
dplhandle() noexcept
|
|
||||||
{}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Initializes a new class instance with an already available object handle.
|
|
||||||
///
|
|
||||||
/// \param[in] h Initial object handle value
|
|
||||||
///
|
|
||||||
dplhandle(_In_opt_ T h) noexcept : handle<T, INVAL>(h)
|
|
||||||
{}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Copy constructor
|
|
||||||
///
|
|
||||||
/// \param[in,out] h A reference of another object
|
|
||||||
///
|
|
||||||
dplhandle<T, INVAL>(_In_ const dplhandle<T, INVAL> &h) : handle<T, INVAL>(duplicate_internal(h.m_h))
|
|
||||||
{}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Move constructor
|
|
||||||
///
|
|
||||||
/// \param[in,out] h A rvalue reference of another object
|
|
||||||
///
|
|
||||||
dplhandle<T, INVAL>(_Inout_ dplhandle<T, INVAL> &&h) noexcept : handle<T, INVAL>(std::move(h))
|
|
||||||
{}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Attaches already available object handle.
|
|
||||||
///
|
|
||||||
/// \param[in] h Object handle value
|
|
||||||
///
|
|
||||||
dplhandle<T, INVAL>& operator=(_In_opt_ T h) noexcept
|
|
||||||
{
|
|
||||||
handle<T, INVAL>::operator=(h);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Duplicates the object.
|
|
||||||
///
|
|
||||||
/// \param[in] h Object
|
|
||||||
///
|
|
||||||
dplhandle<T, INVAL>& operator=(_In_ const dplhandle<T, INVAL> &h) noexcept
|
|
||||||
{
|
|
||||||
if (this != std::addressof(h)) {
|
|
||||||
if (h.m_h != INVAL) {
|
|
||||||
T h_new = duplicate_internal(h.m_h);
|
|
||||||
|
|
||||||
if (this->m_h != INVAL)
|
|
||||||
this->free_internal();
|
|
||||||
|
|
||||||
this->m_h = h_new;
|
|
||||||
} else {
|
|
||||||
if (this->m_h != INVAL)
|
|
||||||
this->free_internal();
|
|
||||||
|
|
||||||
this->m_h = INVAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Moves the object.
|
|
||||||
///
|
|
||||||
/// \param[inout] h A rvalue reference of another object
|
|
||||||
///
|
|
||||||
#pragma warning(disable: 26432) // Move constructor is also present, but not detected by code analysis somehow.
|
|
||||||
dplhandle<T, INVAL>& operator=(_Inout_ dplhandle<T, INVAL> &&h) noexcept
|
|
||||||
{
|
|
||||||
handle<T, INVAL>::operator=(std::move(h));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Duplicates and returns a new object handle.
|
|
||||||
///
|
|
||||||
/// \return Duplicated object handle
|
|
||||||
///
|
|
||||||
T duplicate() const
|
|
||||||
{
|
|
||||||
return this->m_h != INVAL ? duplicate_internal(this->m_h) : INVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Duplicates an object handle and sets a new object handle.
|
|
||||||
///
|
|
||||||
/// \param[in] h Object handle of existing object
|
|
||||||
///
|
|
||||||
void attach_duplicated(_In_opt_ T h)
|
|
||||||
{
|
|
||||||
if (this->m_h != INVAL)
|
|
||||||
this->free_internal();
|
|
||||||
|
|
||||||
this->m_h = h != INVAL ? duplicate_internal(h) : INVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
///
|
|
||||||
/// Abstract member function that must be implemented by child classes to do the actual object handle duplication.
|
|
||||||
/// On failure, it should throw appropriate exception describing the cause, rather than return an invalid handle.
|
|
||||||
///
|
|
||||||
/// \param[in] h Object handle of existing object
|
|
||||||
///
|
|
||||||
/// \return Duplicated object handle
|
|
||||||
///
|
|
||||||
virtual T duplicate_internal(_In_ T h) const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Numerical runtime error
|
/// Numerical runtime error
|
||||||
///
|
///
|
||||||
|
Loading…
x
Reference in New Issue
Block a user