Use C++11 alias templates instead of macro-defined types to implement specialized...
authorJeremy Koritzinsky <jekoritz@microsoft.com>
Thu, 7 May 2020 17:24:20 +0000 (10:24 -0700)
committerGitHub <noreply@github.com>
Thu, 7 May 2020 17:24:20 +0000 (10:24 -0700)
src/coreclr/src/debug/di/process.cpp
src/coreclr/src/inc/appxutil.h
src/coreclr/src/inc/ex.h
src/coreclr/src/inc/holder.h
src/coreclr/src/inc/strongnameholders.h
src/coreclr/src/vm/vmholder.h
src/coreclr/src/vm/wrappers.h

index 4e6fe0b..f13e7b9 100644 (file)
@@ -10990,8 +10990,7 @@ void CordbWin32EventThread::ThreadProc()
 }
 
 // Define a holder that calls code:DeleteIPCEventHelper
-NEW_WRAPPER_TEMPLATE1(DeleteIPCEventHolderHelper, DeleteIPCEventHelper);
-typedef DeleteIPCEventHolderHelper<DebuggerIPCEvent>  DeleteIPCEventHolder;
+using DeleteIPCEventHolder = SpecializedWrapper<DebuggerIPCEvent, DeleteIPCEventHelper>;
 
 //---------------------------------------------------------------------------------------
 //
index c5fce69..644d3b9 100644 (file)
@@ -14,8 +14,6 @@
 
 //---------------------------------------------------------------------------------------------
 // Forward declarations
-template <typename T>
-class NewArrayHolder;
 BOOL WinRTSupported();
 
 
index 21ce9d3..48a3572 100644 (file)
@@ -278,17 +278,13 @@ protected:
 };
 
 #if 1
-template <typename T>
-inline void Exception__Delete(T* pvMemory);
 
-template <>
-inline void Exception__Delete<Exception>(Exception* pvMemory)
+inline void Exception__Delete(Exception* pvMemory)
 {
   Exception::Delete(pvMemory);
 }
 
-NEW_WRAPPER_TEMPLATE1(ExceptionHolderTemplate, Exception__Delete<_TYPE>);
-typedef ExceptionHolderTemplate<Exception> ExceptionHolder;
+using ExceptionHolder = SpecializedWrapper<Exception, Exception__Delete>;
 #else
 
 //------------------------------------------------------------------------------
index c1f86b1..a5781d5 100644 (file)
@@ -824,84 +824,68 @@ class Wrapper : public BaseWrapper<TYPE, FunctionBase<TYPE, ACQUIREF, RELEASEF>,
 #define INDEBUG_AND_WINDOWS_FOR_HOLDERS(x)
 #endif
 
-//---------------------------------------------------------------------------------------
-//
-// New template wrapper type macros.   These save some effort when specializing
-// existing holder templates.  (We would rather use a construct like:
-//
-// template <P1>
-// typedef Holder<...> NewHolder;
-//
-// But this construct doesn't exist in C++.  These macros ease some of the cruft necessary
-// to get similar functionality out of class templates.
-//-----------------------------------------------------------------------------
+template <typename _TYPE, void (*_RELEASEF)(_TYPE*)>
+class SpecializedWrapper : public Wrapper<_TYPE*, DoNothing<_TYPE*>, _RELEASEF, NULL>
+{
+    using BaseT = Wrapper<_TYPE*, DoNothing<_TYPE*>, _RELEASEF, NULL>;
+public:
+    FORCEINLINE SpecializedWrapper() : BaseT(NULL, FALSE)
+    {
+        STATIC_CONTRACT_WRAPPER;
+        INDEBUG_AND_WINDOWS_FOR_HOLDERS(m_pvalue = &this->m_value;)
+    }
+    FORCEINLINE SpecializedWrapper(_TYPE* value) : BaseT(value)
+    {
+        STATIC_CONTRACT_WRAPPER;
+        INDEBUG_AND_WINDOWS_FOR_HOLDERS(m_pvalue = &this->m_value;)
+    }
+    FORCEINLINE SpecializedWrapper(_TYPE* value, BOOL takeOwnership) : BaseT(value, takeOwnership)
+    {
+        STATIC_CONTRACT_WRAPPER;
+        INDEBUG_AND_WINDOWS_FOR_HOLDERS(m_pvalue = &this->m_value;)
+    }
+    FORCEINLINE ~SpecializedWrapper()
+    {
+    }
 
-// Dev10 VC++ has some of the new C++0x language extensions. Of particular interest here:
-// rvalue references, which enables differentiation between named (lvalue) and
-// temporary (rvalue) object references, enabling move semantics and perfect forwarding.
-// See http://msdn.microsoft.com/en-us/library/dd293668.aspx for more information.
-
-// Enable copy construction and assignment from temporary objects. This permits Wrapper objects
-// to be returned from methods, and for move assignment.
-#define NEW_WRAPPER_TEMPLATE_RVALREF_METHODS(_NAME)                                             \
-      public:                                                                                   \
-        FORCEINLINE _NAME(_NAME && other)                                                       \
-        : BaseT(NULL, FALSE)                                                                    \
-        {                                                                                       \
-            STATIC_CONTRACT_WRAPPER;                                                            \
-            INDEBUG_AND_WINDOWS_FOR_HOLDERS(m_pvalue = &this->m_value;)                               \
-            *this = std::move(other);                                                           \
-        }                                                                                       \
-        FORCEINLINE _NAME& operator=(_NAME && other)                                            \
-        {                                                                                       \
-            std::swap(BaseT::m_value, other.BaseT::m_value);                                    \
-            std::swap(BaseT::m_acquired, other.BaseT::m_acquired);                              \
-            return *this;                                                                       \
-        }
+    SpecializedWrapper(SpecializedWrapper const &) = delete;
+    SpecializedWrapper & operator=(SpecializedWrapper const &) = delete;
 
-#define NEW_WRAPPER_TEMPLATE1(_NAME, _RELEASEF)                                                 \
-    template <typename _TYPE>                                                                   \
-    class _NAME : public Wrapper<_TYPE*, DoNothing<_TYPE*>, _RELEASEF, NULL>                    \
-    {                                                                                           \
-        typedef Wrapper<_TYPE*, DoNothing<_TYPE*>, _RELEASEF, NULL> BaseT;                      \
-      public:                                                                                   \
-        FORCEINLINE _NAME() : BaseT(NULL, FALSE)                                                \
-        {                                                                                       \
-            STATIC_CONTRACT_WRAPPER;                                                            \
-            INDEBUG_AND_WINDOWS_FOR_HOLDERS(m_pvalue = &this->m_value;)                               \
-        }                                                                                       \
-        FORCEINLINE _NAME(_TYPE* value) : BaseT(value)                                          \
-        {                                                                                       \
-            STATIC_CONTRACT_WRAPPER;                                                            \
-            INDEBUG_AND_WINDOWS_FOR_HOLDERS(m_pvalue = &this->m_value;)                               \
-        }                                                                                       \
-        FORCEINLINE _NAME(_TYPE* value, BOOL takeOwnership) : BaseT(value, takeOwnership)       \
-        {                                                                                       \
-            STATIC_CONTRACT_WRAPPER;                                                            \
-            INDEBUG_AND_WINDOWS_FOR_HOLDERS(m_pvalue = &this->m_value;)                               \
-        }                                                                                       \
-        FORCEINLINE ~_NAME()                                                                    \
-        {                                                                                       \
-        }                                                                                       \
-        FORCEINLINE _NAME& operator=(_TYPE * value)                                             \
-        {                                                                                       \
-            STATIC_CONTRACT_WRAPPER;                                                            \
-            BaseT::operator=(value);                                                            \
-            return *this;                                                                       \
-        }                                                                                       \
-        /* Since operator& is overloaded we need a way to get a type safe this pointer. */      \
-        FORCEINLINE _NAME* GetAddr()                                                            \
-        {                                                                                       \
-            STATIC_CONTRACT_LEAF;                                                               \
-            return this;                                                                        \
-        }                                                                                       \
-        NEW_WRAPPER_TEMPLATE_RVALREF_METHODS(_NAME)                                             \
-        HIDE_GENERATED_METHODS(_NAME)                                                           \
-      private:                                                                                  \
-        /* m_ppValue: Do not use from source code: Only for convenient use from debugger */     \
-        /*     watch windows - saves five mouseclicks when inspecting holders. */               \
-        INDEBUG_AND_WINDOWS_FOR_HOLDERS(_TYPE ** m_pvalue;)                                     \
-    };
+    FORCEINLINE SpecializedWrapper& operator=(_TYPE * value)
+    {
+        STATIC_CONTRACT_WRAPPER;
+        BaseT::operator=(value);
+        return *this;
+    }
+
+    FORCEINLINE SpecializedWrapper(SpecializedWrapper && other)
+    : BaseT(NULL, FALSE)
+    {
+        STATIC_CONTRACT_WRAPPER;
+        INDEBUG_AND_WINDOWS_FOR_HOLDERS(m_pvalue = &this->m_value;)
+        *this = std::move(other);
+    }
+
+    FORCEINLINE SpecializedWrapper& operator=(SpecializedWrapper && other)
+    {
+        BaseT::m_value = std::move(other.BaseT::m_value);
+        BaseT::m_acquired = std::move(other.BaseT::m_acquired);
+        other.BaseT::m_value = nullptr;
+        other.BaseT::m_acquired = FALSE;
+        return *this;
+    }
+
+    /* Since operator& is overloaded we need a way to get a type safe this pointer. */
+    FORCEINLINE SpecializedWrapper* GetAddr()
+    {
+        STATIC_CONTRACT_LEAF;
+        return this;
+    }
+    private:
+    /* m_ppValue: Do not use from source code: Only for convenient use from debugger */
+    /*     watch windows - saves five mouseclicks when inspecting holders. */
+    INDEBUG_AND_WINDOWS_FOR_HOLDERS(_TYPE ** m_pvalue;)
+};
 
 //-----------------------------------------------------------------------------
 // NOTE: THIS IS UNSAFE TO USE IN THE VM for interop COM objects!!
@@ -930,11 +914,14 @@ FORCEINLINE void DoTheRelease(TYPE *value)
     }
 }
 
-NEW_WRAPPER_TEMPLATE1(DoNothingHolder, DoNothing<_TYPE*>);
+template<typename _TYPE>
+using DoNothingHolder = SpecializedWrapper<_TYPE, DoNothing<_TYPE*>>;
 
-NEW_WRAPPER_TEMPLATE1(ReleaseHolder, DoTheRelease<_TYPE>);
+template<typename _TYPE>
+using ReleaseHolder = SpecializedWrapper<_TYPE, DoTheRelease<_TYPE>>;
 
-NEW_WRAPPER_TEMPLATE1(NonVMComHolder, DoTheRelease<_TYPE>);
+template<typename _TYPE>
+using NonVMComHolder = SpecializedWrapper<_TYPE, DoTheRelease<_TYPE>>;
 
 
 //-----------------------------------------------------------------------------
@@ -957,7 +944,8 @@ FORCEINLINE void StubRelease(TYPE* value)
         value->DecRef();
 }
 
-NEW_WRAPPER_TEMPLATE1(StubHolder, StubRelease<_TYPE>);
+template<typename _TYPE>
+using StubHolder = SpecializedWrapper<_TYPE, StubRelease<_TYPE>>;
 
 //-----------------------------------------------------------------------------
 // CoTaskMemHolder : CoTaskMemAlloc allocated memory holder
@@ -974,7 +962,8 @@ FORCEINLINE void DeleteCoTaskMem(TYPE *value)
         CoTaskMemFree(value);
 }
 
-NEW_WRAPPER_TEMPLATE1(CoTaskMemHolder, DeleteCoTaskMem<_TYPE>);
+template<typename _TYPE>
+using CoTaskMemHolder = SpecializedWrapper<_TYPE, DeleteCoTaskMem<_TYPE>>;
 
 //-----------------------------------------------------------------------------
 // NewHolder : New'ed memory holder
@@ -997,7 +986,8 @@ FORCEINLINE void Delete(TYPE *value)
     delete value;
 }
 
-NEW_WRAPPER_TEMPLATE1(NewHolder, Delete<_TYPE>);
+template<typename _TYPE>
+using NewHolder = SpecializedWrapper<_TYPE, Delete<_TYPE>>;
 
  //-----------------------------------------------------------------------------
 // NewExecutableHolder : New'ed memory holder for executable memory.
@@ -1009,7 +999,8 @@ NEW_WRAPPER_TEMPLATE1(NewHolder, Delete<_TYPE>);
 // IJW
 template<class T> void DeleteExecutable(T *p);
 
-NEW_WRAPPER_TEMPLATE1(NewExecutableHolder, DeleteExecutable<_TYPE>);
+template<typename _TYPE>
+using NewExecutableHolder = SpecializedWrapper<_TYPE, DeleteExecutable<_TYPE>>;
 
 //-----------------------------------------------------------------------------
 // NewArrayHolder : New []'ed pointer holder
@@ -1026,7 +1017,8 @@ FORCEINLINE void DeleteArray(TYPE *value)
     value = NULL;
 }
 
-NEW_WRAPPER_TEMPLATE1(NewArrayHolder, DeleteArray<_TYPE>);
+template<typename _TYPE>
+using NewArrayHolder = SpecializedWrapper<_TYPE, DeleteArray<_TYPE>>;
 typedef NewArrayHolder<CHAR>  AStringHolder;
 typedef NewArrayHolder<WCHAR> WStringHolder;
 
@@ -1113,8 +1105,10 @@ namespace detail
 }
 #undef VISIBLE
 
-NEW_WRAPPER_TEMPLATE1(ResetPointerHolder, detail::ZeroMem<_TYPE>::Invoke);
-NEW_WRAPPER_TEMPLATE1(FieldNuller, detail::ZeroMem<_TYPE>::Invoke);
+template<typename _TYPE>
+using ResetPointerHolder = SpecializedWrapper<_TYPE, detail::ZeroMem<_TYPE>::Invoke>;
+template<typename _TYPE>
+using FieldNuller = SpecializedWrapper<_TYPE, detail::ZeroMem<_TYPE>::Invoke>;
 
 //-----------------------------------------------------------------------------
 // Wrap win32 functions using HANDLE
@@ -1157,7 +1151,8 @@ typedef Wrapper<HMODULE, DoNothing<HMODULE>, HolderFreeLibrary, NULL> HModuleHol
 template <typename T> FORCEINLINE
 void DoLocalFree(T* pMem) { (LocalFree)((HLOCAL)pMem); }
 
-NEW_WRAPPER_TEMPLATE1(LocalAllocHolder, DoLocalFree<_TYPE>);
+template<typename _TYPE>
+using LocalAllocHolder = SpecializedWrapper<_TYPE, DoLocalFree<_TYPE>>;
 
 inline void BoolSet( _Out_ bool * val ) { *val = true; }
 inline void BoolUnset( _Out_ bool * val ) { *val = false; }
index ecec994..d684e9d 100644 (file)
@@ -18,6 +18,7 @@ void VoidStrongNameFreeBuffer(__in T *pBuffer)
 {
     StrongNameFreeBuffer(reinterpret_cast<BYTE *>(pBuffer));
 }
-NEW_WRAPPER_TEMPLATE1(StrongNameBufferHolder, VoidStrongNameFreeBuffer<_TYPE>);
+template<typename _TYPE>
+using StrongNameBufferHolder = SpecializedWrapper<_TYPE, VoidStrongNameFreeBuffer<_TYPE>>;
 
 #endif // !__STRONGNAME_HOLDERS_H__
index 9c265a1..003892b 100644 (file)
@@ -18,6 +18,7 @@ inline void DoTheReleaseHost(TYPE *value)
     }
 }
 
-NEW_WRAPPER_TEMPLATE1(HostComHolder, DoTheReleaseHost<_TYPE>);
+template<typename _TYPE>
+using HostComHolder = SpecializedWrapper<_TYPE, DoTheReleaseHost<_TYPE>>;
 
 #endif
index b9e40e8..a256cb5 100644 (file)
@@ -109,11 +109,13 @@ inline void SafeComReleasePreemp(TYPE *value)
     SafeReleasePreemp((IUnknown*)value);
 }
 
-NEW_WRAPPER_TEMPLATE1(SafeComHolder, SafeComRelease<_TYPE>);
+template<typename _TYPE>
+using SafeComHolder = SpecializedWrapper<_TYPE, SafeComRelease<_TYPE>>;
 
 // Use this holder if you're already in preemptive mode for other reasons,
 // use SafeComHolder otherwise.
-NEW_WRAPPER_TEMPLATE1(SafeComHolderPreemp, SafeComReleasePreemp<_TYPE>);
+template<typename _TYPE>
+using SafeComHolderPreemp = SpecializedWrapper<_TYPE, SafeComReleasePreemp<_TYPE>>;
 
 
 
@@ -166,7 +168,8 @@ void DeletePreemp(TYPE *value)
     delete value;
 }
 
-NEW_WRAPPER_TEMPLATE1(NewPreempHolder, DeletePreemp<_TYPE>);
+template<typename _TYPE>
+using NewPreempHolder = SpecializedWrapper<_TYPE, DeletePreemp<_TYPE>>;
 
 
 //-----------------------------------------------------------------------------