#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!!
}
}
-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>>;
//-----------------------------------------------------------------------------
value->DecRef();
}
-NEW_WRAPPER_TEMPLATE1(StubHolder, StubRelease<_TYPE>);
+template<typename _TYPE>
+using StubHolder = SpecializedWrapper<_TYPE, StubRelease<_TYPE>>;
//-----------------------------------------------------------------------------
// CoTaskMemHolder : CoTaskMemAlloc allocated memory holder
CoTaskMemFree(value);
}
-NEW_WRAPPER_TEMPLATE1(CoTaskMemHolder, DeleteCoTaskMem<_TYPE>);
+template<typename _TYPE>
+using CoTaskMemHolder = SpecializedWrapper<_TYPE, DeleteCoTaskMem<_TYPE>>;
//-----------------------------------------------------------------------------
// NewHolder : New'ed memory holder
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.
// 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
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;
}
#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
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; }