text: //
  // Copyright (C) Microsoft Corporation
  // All rights reserved.
  //
  // Code in Details namespace is for internal usage within the library code
  //
  
  #ifndef _WRL_IMPLEMENTS_H_
  #define _WRL_IMPLEMENTS_H_
  
  #ifdef _MSC_VER
  #pragma once
  #endif  // _MSC_VER
  
  #pragma region includes
  
  #include <inspectable.h>
  #include <roapi.h>
  #ifdef BUILD_WINDOWS
  #include <winrt.h>
  #endif
  #include <activation.h>
  #include <WinString.h>
  
  #include <new.h>
  #include <weakreference.h>
  #include <objbase.h>    // IMarshal
  #include <cguid.h>      // CLSID_StdGlobalInterfaceTable
  #include <intrin.h>
  
  #include <wrl/def.h>
  #include <wrl/client.h>
  
  #if (NTDDI_VERSION >= NTDDI_WINBLUE)
  #include "roerrorapi.h"
  #endif // (NTDDI_VERSION >= NTDDI_WINBLUE)
  
  // Set packing
  #include <pshpack8.h>
  
  #pragma endregion
  
  #ifndef __WRL_NO_DEFAULT_LIB__
  #pragma comment(lib, "ole32.lib") // For CoTaskMemAlloc
  #endif
  
  #pragma region disable warnings
  
  #pragma warning(push)
  #pragma warning(disable: 4584) // 'class1' : base-class 'class2' is already a base-class of 'class3'
  #pragma warning(disable: 4481) // nonstandard extension used: override specifier 'override'
  
  #pragma endregion // disable warnings
  
  namespace Microsoft {
  namespace WRL {
  
  // Indicator for RuntimeClass,Implements and ChainInterfaces that T interface
  // will be not accessible on IID list
  // Example:
  // struct MyRuntimeClass : RuntimeClass<CloakedIid<IMyCloakedInterface>> {}
  template<typename T>
  struct CloakedIid : T
  {
  };
  
  enum RuntimeClassType
  {
      WinRt                   = 0x0001,
      ClassicCom              = 0x0002,
      WinRtClassicComMix      = WinRt | ClassicCom,
      InhibitWeakReference    = 0x0004,
      Delegate                = ClassicCom,
      InhibitFtmBase          = 0x0008,
      InhibitRoOriginateError = 0x0010
  };
  
  template <unsigned int flags>
  struct RuntimeClassFlags
  {
      static const unsigned int value = flags;
  };
  
  namespace Details
  {
  // Empty struct used for validating template parameter types in Implements
  struct ImplementsBase
  {
  };
  
  } // namespace Details
  
  // MixIn modifier allows to combine QI from
  // a class that doesn't have default constructor on it
  template<typename Derived, typename MixInType, bool hasImplements = __is_base_of(Details::ImplementsBase, MixInType)>
  struct MixIn
  {
  };
  
  // ComposableBase template to allow deriving from a RuntimeClass
  // Optionally allows specifying the base factory and statics interface
  template <typename FactoryInterface = IInspectable>
  class ComposableBase
  {
  };
  // Back-compat indicator for RuntimeClass to not support IWeakReferenceSource
  typedef RuntimeClassFlags<WinRt | InhibitWeakReference>    InhibitWeakReferencePolicy;
  
  template<unsigned int RuntimeClassTypeT>
  struct ErrorHelper
  {
      static void OriginateError(HRESULT hr, HSTRING message)
      {
  #if (NTDDI_VERSION >= NTDDI_WINBLUE)
          ::RoOriginateError(hr, message);
  #else
          UNREFERENCED_PARAMETER(hr);
          UNREFERENCED_PARAMETER(message);
  #endif // (NTDDI_VERSION >= NTDDI_WINBLUE)
      }
  };
  
  template<>
  struct ErrorHelper<InhibitRoOriginateError>
  {
      static void OriginateError(HRESULT hr, HSTRING message)
      {
          UNREFERENCED_PARAMETER(hr);
          UNREFERENCED_PARAMETER(message);
          // No-Op
      }
  };
  
  namespace Details
  {
  
  //Forward declaration
  struct CreatorMap;
  
  // Sections automatically generate a list of pointers to CreatorMap through the linker
  // Sections a and z are used as a terminators
  #pragma section("minATL$__a", read)
  // Section f is used to put com objects to creator map
  #pragma section("minATL$__f", read)
  // Section m divides COM entries from WinRT entries
  #pragma section("minATL$__m", read)
  // Section r is used to put WinRT objects to creator map
  #pragma section("minATL$__r", read)
  #pragma section("minATL$__z", read)
  
  extern "C"
  {
  // Location of the first and last entries for the linker generated list of pointers to CreatorMapEntry
  __declspec(selectany) __declspec(allocate("minATL$__a")) const CreatorMap* __pobjectentryfirst = nullptr;
  // Section m divides COM objects from WinRT objects
  // - sections between a and m we store COM object info
  // - sections between m+1 and z we store WinRT object info 
  __declspec(selectany) __declspec(allocate("minATL$__m")) const CreatorMap* __pobjectentrymid = nullptr;
  __declspec(selectany) __declspec(allocate("minATL$__z")) const CreatorMap* __pobjectentrylast = nullptr;
  }
  
  // Base class used by all module classes.
  class __declspec(novtable) ModuleBase
  {
  private:
      // Lock that synchronize access and termination of factories
      static void* moduleLock_;
  
      static_assert(sizeof(moduleLock_) == sizeof(SRWLOCK), "cacheLock must have the same size as SRWLOCK");
  protected:
      static volatile unsigned long objectCount_;
  public:
      static ModuleBase *module_;
  
      ModuleBase() throw()
      {
  #ifdef _DEBUG
          // WRLs support for activatable classes requires there is only one instance of Module<>, this assert
          // ensures there is only one. Since Module<> is templatized, using different template parameters will
          // result in multiple instances, avoid this by making sure all code in a component uses the same parameters.
          // Note that the C++ CX runtime creates an instance; Module<InProc, Platform::Details::InProcModule>,
          // so mixing it with non CX code can result in this assert.
          // WRL supports static and dynamically allocated Module<>, choose dynamic by defining __WRL_DISABLE_STATIC_INITIALIZE__
          // and allocate that instance with new but only once, for example in the main() entry point of an application.
          __WRL_ASSERT__(::InterlockedCompareExchangePointer(reinterpret_cast<void* volatile*>(&module_), this, nullptr) == nullptr &&
              "The module was already instantiated");
  
          SRWLOCK initSRWLOCK = SRWLOCK_INIT;
          __WRL_ASSERT__(reinterpret_cast<SRWLOCK*>(&moduleLock_)->Ptr == initSRWLOCK.Ptr && "Different value for moduleLock_ than SRWLOCK_INIT");
          (initSRWLOCK);
  #else
          module_ = this;
  #endif
      }
  
      ModuleBase(const ModuleBase&) = delete;
      ModuleBase& operator=(const ModuleBase&) = delete;
  
      virtual ~ModuleBase() throw()
      {
  #ifdef _DEBUG
          __WRL_ASSERT__(::InterlockedCompareExchangePointer(reinterpret_cast<void* volatile*>(&module_), nullptr, this) == this &&
              "The module was already instantiated");
  #else
          module_ = nullptr;
  #endif
      }
  
      // Number of active objects in the module
      STDMETHOD_(unsigned long, IncrementObjectCount)() = 0;
      STDMETHOD_(unsigned long, DecrementObjectCount)() = 0;
  
      STDMETHOD_(unsigned long, GetObjectCount)() const
      {
          return objectCount_;
      }
  
      STDMETHOD_(const CreatorMap**, GetFirstEntryPointer)() const
      {
          return &__pobjectentryfirst;
      }
  
      STDMETHOD_(const CreatorMap**, GetMidEntryPointer)() const
      {
          return &__pobjectentrymid;
      }
  
      STDMETHOD_(const CreatorMap**, GetLastEntryPointer)() const
      {
          return &__pobjectentrylast;
      }
  
      STDMETHOD_(SRWLOCK*, GetLock)() const
      {
          return reinterpret_cast<SRWLOCK*>(&moduleLock_);
      }
  
      STDMETHOD(RegisterWinRTObject)(_In_opt_z_ const wchar_t*, _In_z_ const wchar_t** activatableClassIds, _Inout_ RO_REGISTRATION_COOKIE* cookie, unsigned int) = 0;
      STDMETHOD(UnregisterWinRTObject)(_In_opt_z_ const wchar_t*, _In_ RO_REGISTRATION_COOKIE) = 0;
      STDMETHOD(RegisterCOMObject)(_In_opt_z_ const wchar_t*, _In_ IID*, _In_ IClassFactory**, _Inout_ DWORD*, unsigned int) = 0;
      STDMETHOD(UnregisterCOMObject)(_In_opt_z_ const wchar_t*, _Inout_ DWORD*, unsigned int) = 0;
  };
  
  __declspec(selectany) volatile unsigned long ModuleBase::objectCount_ = 0;
  // moduleLock_ value must be equal SRWLOCK_INIT which is nullptr
  __declspec(selectany) void* ModuleBase::moduleLock_ = nullptr;
  __declspec(selectany) ModuleBase *ModuleBase::module_ = nullptr;
  
  #pragma region helper types
  // Empty struct used as default template parameter
  class Nil 
  {
  };
  
  // Used on RuntimeClass to protect it from being constructed with new
  class DontUseNewUseMake
  {
  private:
      void* operator new(size_t) throw()
      {
          __WRL_ASSERT__(false);
          return 0;
      }
  
  public:
      void* operator new(size_t, _In_ void* placement) throw()
      {
          return placement;
      }
  };
  
  // RuntimeClassBase is used for detection of RuntimeClass in Make method
  class RuntimeClassBase
  {
  };
  
  // RuntimeClassBaseT provides helper methods for QI and getting IIDs 
  template <unsigned int RuntimeClassTypeT>
  class RuntimeClassBaseT : private RuntimeClassBase
  {
  protected:
      template<typename T>
      static HRESULT AsIID(_In_ T* implements, REFIID riid, _Outptr_result_nullonfailure_ void **ppvObject) throw()
      {
          *ppvObject = nullptr;
  #pragma warning(push)
  // Conditional expression is constant
  #pragma warning(disable: 4127)
  // Potential comparison of a constant with another constant
  #pragma warning(disable: 6326)
  // Conditional check using template parameter is constant and can be used to optimize the code
          bool isRefDelegated = false;
          // Prefer InlineIsEqualGUID over other forms since it's better perf on 4-byte aligned data, which is almost always the case.
          if (InlineIsEqualGUID(riid, __uuidof(IUnknown)) || ((RuntimeClassTypeT & WinRt) != 0 && InlineIsEqualGUID(riid, __uuidof(IInspectable))))
  #pragma warning(pop)
          {
              *ppvObject = implements->CastToUnknown();
              static_cast<IUnknown*>(*ppvObject)->AddRef();
              return S_OK;
          }
          
          HRESULT hr = implements->CanCastTo(riid, ppvObject, &isRefDelegated);        
          if (SUCCEEDED(hr) && !isRefDelegated)
          {
              static_cast<IUnknown*>(*ppvObject)->AddRef();
          }
  
  #pragma warning(suppress: 6102) // '*ppvObject' is used but may not be initialized
          _Analysis_assume_(SUCCEEDED(hr) || (*ppvObject == nullptr));
  
          return hr;
      }
      template<typename T>
      static HRESULT GetImplementedIIDS(
          _In_ T* implements,            
          _Out_ ULONG *iidCount,
          _When_(*iidCount == 0, _At_(*iids, _Post_null_))
          _When_(*iidCount > 0, _At_(*iids, _Post_notnull_))
          _Result_nullonfailure_ IID **iids) throw()
      {
          *iids = nullptr;
          *iidCount = 0;
          unsigned long count = implements->GetIidCount();
  
          // If there is no iids the CoTaskMemAlloc don't have to be called
          if (count == 0)
          {
              return S_OK;
          }
  
          IID* iidArray = reinterpret_cast<IID*>(::CoTaskMemAlloc(sizeof(IID) * count));
          if (iidArray == nullptr)
          {
              return E_OUTOFMEMORY;
          }
  
          unsigned long index = 0;
  
          // assign the IIDs to the array
          implements->FillArrayWithIid(&index, iidArray);
          __WRL_ASSERT__(index == count);
  
          // and return it
          *iidCount = count;
          *iids = iidArray;
          return S_OK;
      }
  
  public:
      HRESULT RuntimeClassInitialize() throw()
      {
          return S_OK;
      }
  };
  
  // Base class required to mark FtmBase
  class FtmBaseMarker
  {
  };
  
  // Verifies that I is derived from specified base
  template <unsigned int type, typename I, bool doStrictCheck = true, bool isImplementsBased = __is_base_of(ImplementsBase, I)>
  struct VerifyInterfaceHelper;
  
  // Specialization for ClassicCom interface
  template <typename I, bool doStrictCheck>
  struct VerifyInterfaceHelper<ClassicCom, I, doStrictCheck, false>
  {
      static void Verify() throw()
      {
  #ifdef __WRL_STRICT__
          // Make sure that your interfaces inherit from IUnknown and are not IUnknown and/or IInspectable based
          // The IUnknown is allowed only on RuntimeClass as first template parameter
          static_assert(__is_base_of(IUnknown, I) && !__is_base_of(IInspectable, I) && !(doStrictCheck && IsSame<IUnknown, I>::value),
              "'I' has to derive from 'IUnknown' and not from 'IInspectable'. 'I' must not be IUnknown.");
  #else
          static_assert(__is_base_of(IUnknown, I), "'I' has to derive from 'IUnknown'.");
  #endif
      }
  };
  
  // Specialization for WinRtClassicComMix interface
  template <typename I, bool doStrictCheck>
  struct VerifyInterfaceHelper<WinRtClassicComMix, I, doStrictCheck, false>
  {
      static void Verify() throw()
      {
  #ifdef __WRL_STRICT__
          // Make sure that your interfaces inherit from IUnknown and are not IUnknown and/or IInspectable
          // except when IInspectable is the first template parameter
          static_assert(__is_base_of(IUnknown, I) && 
              (doStrictCheck ? !(IsSame<IInspectable, I>::value || IsSame<IUnknown, I>::value) : __is_base_of(IInspectable, I)),
                  "'I' has to derive from 'IUnknown' and must not be IUnknown and/or IInspectable.");
  #else
          static_assert(__is_base_of(IUnknown, I), "'I' has to derive from 'IUnknown'.");
  #endif
      }    
  };
  
  // Specialization for WinRt interface
  template <typename I, bool doStrictCheck>
  struct VerifyInterfaceHelper<WinRt, I, doStrictCheck, false>
  {
      static void Verify() throw()
      {
  #ifdef __WRL_STRICT__
          // IWeakReferenceSource is exception for WinRt and can be used however it cannot be first templated interface
          // Make sure that your interfaces inherit from IInspectable and are not IInspectable
          // The IInspectable is allowed only on RuntimeClass as first template parameter
          static_assert((__is_base_of(IWeakReferenceSource, I) && doStrictCheck) || 
              (__is_base_of(IInspectable, I) && !(doStrictCheck && IsSame<IInspectable, I>::value)), 
                  "'I' has to derive from 'IWeakReferenceSource' or 'IInspectable' and must not be IInspectable");
  #else
          // IWeakReference and IWeakReferneceSource are exceptions for WinRT
          static_assert(__is_base_of(IWeakReference, I) ||
                          __is_base_of(IWeakReferenceSource, I) ||
                              __is_base_of(IInspectable, I), "'I' has to derive from 'IWeakReference', 'IWeakReferenceSource' or 'IInspectable'");
  #endif
      }
  };
  
  // Specialization for Implements passed as template parameter
  template <unsigned int type, typename I>
  struct VerifyInterfaceHelper<type, I, true, true>
  {
      static void Verify() throw()
      {
  #ifdef __WRL_STRICT__
          // Verifies if Implements has correct RuntimeClassFlags setting
          // Allow using FtmBase on classes configured with RuntimeClassFlags<WinRt> (Default configuration)
          static_assert(I::ClassFlags::value == type ||
                  type == WinRtClassicComMix ||
                      __is_base_of(::Microsoft::WRL::Details::FtmBaseMarker, I),
              "Implements class must have the same and/or compatibile flags configuration");
  #endif
      }
  };
  
  // Specialization for Implements passed as first template parameter
  template <unsigned int type, typename I>
  struct VerifyInterfaceHelper<type, I, false, true>
  {
      static void Verify() throw()
      {
  #ifdef __WRL_STRICT__
          // Verifies if Implements has correct RuntimeClassFlags setting
          static_assert(I::ClassFlags::value == type || type == WinRtClassicComMix,
              "Implements class must have the same and/or compatible flags configuration."
                  "If you use WRL::FtmBase it cannot be specified as first template parameter on RuntimeClass");
              
          // Besides make sure that the first interface on Implements meet flags requirement
          VerifyInterfaceHelper<type, I::FirstInterface, false>::Verify();
  #endif
      }
  };
  
  // Interface traits provides casting and filling iids methods helpers
  template<typename I0>
  struct __declspec(novtable) InterfaceTraits
  {
      typedef I0 Base;    
      static const unsigned long IidCount = 1;
  
      template<unsigned int ClassType>
      static void Verify() throw()
      {
          VerifyInterfaceHelper<ClassType & WinRtClassicComMix, Base>::Verify();
      }
  
      template<typename T>
      static Base* CastToBase(_In_ T* ptr) throw()
      {
          return static_cast<Base*>(ptr);
      }
  
      template<typename T>
      static IUnknown* CastToUnknown(_In_ T* ptr) throw()
      {
          return static_cast<IUnknown*>(static_cast<Base*>(ptr));
      }
  
      template <typename T>
      _Success_(return == true)
      static bool CanCastTo(_In_ T* ptr, REFIID riid, _Outptr_ void **ppv) throw()
      {
          // Prefer InlineIsEqualGUID over other forms since it's better perf on 4-byte aligned data, which is almost always the case.
          if (InlineIsEqualGUID(riid, __uuidof(Base)))
          {
              *ppv = static_cast<Base*>(ptr);
              return true;
          }
  
          return false;
      }
  
      static void FillArrayWithIid(_Inout_ unsigned long *index, _Inout_ IID* iids) throw()
      {
          *(iids + *index) = __uuidof(Base);
          (*index)++;
      }
  };
  
  // Specialization of traits for cloaked interface
  template<typename CloakedType>
  struct __declspec(novtable) InterfaceTraits<CloakedIid<CloakedType>>
  {
      typedef CloakedType Base;
      static const unsigned long IidCount = 0;
  
      template<unsigned int ClassType>
      static void Verify() throw()
      {
          VerifyInterfaceHelper<ClassType & WinRtClassicComMix, Base>::Verify();
      }
  
      template<typename T>
      static Base* CastToBase(_In_ T* ptr) throw()
      {
          return static_cast<Base*>(ptr);
      }
  
      template<typename T>
      static IUnknown* CastToUnknown(_In_ T* ptr) throw()
      {
          return static_cast<IUnknown*>(static_cast<Base*>(ptr));
      }
  
      template <typename T>
      _Success_(return == true)
      static bool CanCastTo(_In_ T* ptr, REFIID riid, _Outptr_ void **ppv) throw()
      {
          // Prefer InlineIsEqualGUID over other forms since it's better perf on 4-byte aligned data, which is almost always the case.
          if (InlineIsEqualGUID(riid, __uuidof(Base)))
          {
              *ppv = static_cast<Base*>(ptr);
              return true;
          }
  
          return false;
      }
  
      // Cloaked specialization makes it always IID list empty
      static void FillArrayWithIid(_Inout_ unsigned long*, _Inout_ IID*) throw()
      {
      }
  };
  
  // Specialization for Nil parameter
  template<>
  struct __declspec(novtable) InterfaceTraits<Nil>
  {
      typedef Nil Base;
      static const unsigned long IidCount = 0;
  
      template<unsigned int ClassType>
      static void Verify() throw()
      {
      }
  
      static void FillArrayWithIid(_Inout_ unsigned long *, _Inout_ IID*) throw()
      {
      }
  
      template <typename T>
      _Success_(return == true)
      static bool CanCastTo(_In_ T*, REFIID, _Outptr_ void **) throw()
      {
          return false;
      }
  };
  
  // Verify inheritance
  template <typename I, typename Base>
  struct VerifyInheritanceHelper
  {
      static void Verify() throw()
      {
          static_assert(Details::IsBaseOfStrict<typename InterfaceTraits<Base>::Base, typename InterfaceTraits<I>::Base>::value, "'I' needs to inherit from 'Base'.");
      }
  };
  
  template <typename I>
  struct VerifyInheritanceHelper<I, Nil>
  {
      static void Verify() throw()
      {
      }
  };
  
  #pragma endregion //  helper types
  
  } // namespace Details
  
  inline Details::ModuleBase* GetModuleBase() throw()
  {
      return Details::ModuleBase::module_;
  }
  
  // ChainInterfaces - template allows specifying a derived COM interface along with its class hierarchy to allow QI for the base interfaces
  template <typename I0, typename I1, typename I2 = Details::Nil, typename I3 = Details::Nil, 
          typename I4 = Details::Nil, typename I5 = Details::Nil, typename I6 = Details::Nil,
          typename I7 = Details::Nil, typename I8 = Details::Nil, typename I9 = Details::Nil>
  struct ChainInterfaces : I0
  {
  protected:    
      template<unsigned int ClassType>
      static void Verify() throw()
      {
          Details::InterfaceTraits<I0>::template Verify<ClassType>();
          Details::InterfaceTraits<I1>::template Verify<ClassType>();
          Details::InterfaceTraits<I2>::template Verify<ClassType>();
          Details::InterfaceTraits<I3>::template Verify<ClassType>();
          Details::InterfaceTraits<I4>::template Verify<ClassType>();
          Details::InterfaceTraits<I5>::template Verify<ClassType>();
          Details::InterfaceTraits<I6>::template Verify<ClassType>();
          Details::InterfaceTraits<I7>::template Verify<ClassType>();
          Details::InterfaceTraits<I8>::template Verify<ClassType>();
          Details::InterfaceTraits<I9>::template Verify<ClassType>();
  
          Details::VerifyInheritanceHelper<I0, I1>::Verify();
          Details::VerifyInheritanceHelper<I0, I2>::Verify();
          Details::VerifyInheritanceHelper<I0, I3>::Verify();
          Details::VerifyInheritanceHelper<I0, I4>::Verify();
          Details::VerifyInheritanceHelper<I0, I5>::Verify();
          Details::VerifyInheritanceHelper<I0, I6>::Verify();
          Details::VerifyInheritanceHelper<I0, I7>::Verify();
          Details::VerifyInheritanceHelper<I0, I8>::Verify();
          Details::VerifyInheritanceHelper<I0, I9>::Verify();
      }
  
      HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv) throw()
      {
          typename Details::InterfaceTraits<I0>::Base* ptr = Details::InterfaceTraits<I0>::CastToBase(this);
  
          return (Details::InterfaceTraits<I0>::CanCastTo(this, riid, ppv) ||
              Details::InterfaceTraits<I1>::CanCastTo(ptr, riid, ppv) ||
              Details::InterfaceTraits<I2>::CanCastTo(ptr, riid, ppv) ||
              Details::InterfaceTraits<I3>::CanCastTo(ptr, riid, ppv) ||
              Details::InterfaceTraits<I4>::CanCastTo(ptr, riid, ppv) ||
              Details::InterfaceTraits<I5>::CanCastTo(ptr, riid, ppv) ||
              Details::InterfaceTraits<I6>::CanCastTo(ptr, riid, ppv) ||
              Details::InterfaceTraits<I7>::CanCastTo(ptr, riid, ppv) ||
              Details::InterfaceTraits<I8>::CanCastTo(ptr, riid, ppv) ||
              Details::InterfaceTraits<I9>::CanCastTo(ptr, riid, ppv)) ? S_OK : E_NOINTERFACE;
      }
  
      IUnknown* CastToUnknown() throw()
      {
          return Details::InterfaceTraits<I0>::CastToUnknown(this);
      }
  
      static const unsigned long IidCount = 
          Details::InterfaceTraits<I0>::IidCount + 
          Details::InterfaceTraits<I1>::IidCount +
          Details::InterfaceTraits<I2>::IidCount +
          Details::InterfaceTraits<I3>::IidCount +
          Details::InterfaceTraits<I4>::IidCount +
          Details::InterfaceTraits<I5>::IidCount +
          Details::InterfaceTraits<I6>::IidCount +
          Details::InterfaceTraits<I7>::IidCount +
          Details::InterfaceTraits<I8>::IidCount +
          Details::InterfaceTraits<I9>::IidCount;
  
      static void FillArrayWithIid(_Inout_ unsigned long *index, _Inout_ IID* iids) throw()
      {
          Details::InterfaceTraits<I0>::FillArrayWithIid(index, iids);
          Details::InterfaceTraits<I1>::FillArrayWithIid(index, iids);
          Details::InterfaceTraits<I2>::FillArrayWithIid(index, iids);
          Details::InterfaceTraits<I3>::FillArrayWithIid(index, iids);
          Details::InterfaceTraits<I4>::FillArrayWithIid(index, iids);
          Details::InterfaceTraits<I5>::FillArrayWithIid(index, iids);
          Details::InterfaceTraits<I6>::FillArrayWithIid(index, iids);
          Details::InterfaceTraits<I7>::FillArrayWithIid(index, iids);
          Details::InterfaceTraits<I8>::FillArrayWithIid(index, iids);
          Details::InterfaceTraits<I9>::FillArrayWithIid(index, iids);
      }
  };
  
  template <typename DerivedType, typename BaseType, bool hasImplements, typename I1, typename I2, typename I3, 
          typename I4, typename I5, typename I6,
          typename I7, typename I8, typename I9>
  struct ChainInterfaces<MixIn<DerivedType, BaseType, hasImplements>, I1, I2, I3, I4, I5, I6, I7, I8, I9>
  {
      static_assert(!hasImplements, "Cannot use ChainInterfaces<MixIn<...>> to Mix a class implementing interfaces using \"Implements\"");
  
  protected:    
      template<unsigned int ClassType>
      static void Verify() throw()
      {
          Details::InterfaceTraits<BaseType>::template Verify<ClassType>();
          Details::InterfaceTraits<I1>::template Verify<ClassType>();
          Details::InterfaceTraits<I2>::template Verify<ClassType>();
          Details::InterfaceTraits<I3>::template Verify<ClassType>();
          Details::InterfaceTraits<I4>::template Verify<ClassType>();
          Details::InterfaceTraits<I5>::template Verify<ClassType>();
          Details::InterfaceTraits<I6>::template Verify<ClassType>();
          Details::InterfaceTraits<I7>::template Verify<ClassType>();
          Details::InterfaceTraits<I8>::template Verify<ClassType>();
          Details::InterfaceTraits<I9>::template Verify<ClassType>();
  
          Details::VerifyInheritanceHelper<BaseType, I1>::Verify();
          Details::VerifyInheritanceHelper<BaseType, I2>::Verify();
          Details::VerifyInheritanceHelper<BaseType, I3>::Verify();
          Details::VerifyInheritanceHelper<BaseType, I4>::Verify();
          Details::VerifyInheritanceHelper<BaseType, I5>::Verify();
          Details::VerifyInheritanceHelper<BaseType, I6>::Verify();
          Details::VerifyInheritanceHelper<BaseType, I7>::Verify();
          Details::VerifyInheritanceHelper<BaseType, I8>::Verify();
          Details::VerifyInheritanceHelper<BaseType, I9>::Verify();
      }
  
      HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv) throw()
      {
          BaseType* ptr = static_cast<BaseType*>(static_cast<DerivedType*>(this));
  
          return (
              Details::InterfaceTraits<I1>::CanCastTo(ptr, riid, ppv) ||
              Details::InterfaceTraits<I2>::CanCastTo(ptr, riid, ppv) ||
              Details::InterfaceTraits<I3>::CanCastTo(ptr, riid, ppv) ||
              Details::InterfaceTraits<I4>::CanCastTo(ptr, riid, ppv) ||
              Details::InterfaceTraits<I5>::CanCastTo(ptr, riid, ppv) ||
              Details::InterfaceTraits<I6>::CanCastTo(ptr, riid, ppv) ||
              Details::InterfaceTraits<I7>::CanCastTo(ptr, riid, ppv) ||
              Details::InterfaceTraits<I8>::CanCastTo(ptr, riid, ppv) ||
              Details::InterfaceTraits<I9>::CanCastTo(ptr, riid, ppv)) ? S_OK : E_NOINTERFACE;
      }
  
      // It's not possible to cast to IUnknown when Base interface inherit more interfaces
      // The RuntimeClass is taking always the first interface as IUnknown thus it's required to
      // list IInspectable or IUnknown class before MixIn<Derived, MixInType> parameter, such as:
      // struct MyRuntimeClass : RuntimeClass<IInspectable, ChainInterfaces<MixIn<MyRuntimeClass,MyIndependentImplementation>, IFoo, IBar>, MyIndependentImplementation  {}
      IUnknown* CastToUnknown() throw() = delete;
  
      static const unsigned long IidCount = 
          Details::InterfaceTraits<I1>::IidCount +
          Details::InterfaceTraits<I2>::IidCount +
          Details::InterfaceTraits<I3>::IidCount +
          Details::InterfaceTraits<I4>::IidCount +
          Details::InterfaceTraits<I5>::IidCount +
          Details::InterfaceTraits<I6>::IidCount +
          Details::InterfaceTraits<I7>::IidCount +
          Details::InterfaceTraits<I8>::IidCount +
          Details::InterfaceTraits<I9>::IidCount;
  
      static void FillArrayWithIid(_Inout_ unsigned long *index, _Inout_ IID* iids) throw()
      {
          Details::InterfaceTraits<I1>::FillArrayWithIid(index, iids);
          Details::InterfaceTraits<I2>::FillArrayWithIid(index, iids);
          Details::InterfaceTraits<I3>::FillArrayWithIid(index, iids);
          Details::InterfaceTraits<I4>::FillArrayWithIid(index, iids);
          Details::InterfaceTraits<I5>::FillArrayWithIid(index, iids);
          Details::InterfaceTraits<I6>::FillArrayWithIid(index, iids);
          Details::InterfaceTraits<I7>::FillArrayWithIid(index, iids);
          Details::InterfaceTraits<I8>::FillArrayWithIid(index, iids);
          Details::InterfaceTraits<I9>::FillArrayWithIid(index, iids);
      }
  };
  
  namespace Details
  {
  
  #pragma region Implements helper templates
  
  // Helper template used by Implements. This template traverses a list of interfaces and adds them as base class and information
  // to enable QI. doStrictCheck is typically false only for the first interface, allowing IInspectable to be explicitly specified 
  // only as the first interface.
  template <typename RuntimeClassFlagsT, bool doStrictCheck, typename ...TInterfaces>
  struct __declspec(novtable) ImplementsHelper;
  
  template <typename T>
  struct __declspec(novtable) ImplementsMarker
  {};
  
  template <typename I0, bool isImplements>
  struct __declspec(novtable) MarkImplements;
  
  template <typename I0>
  struct __declspec(novtable) MarkImplements<I0, false>
  {
      typedef I0 Type;
  };
  
  template <typename I0>
  struct __declspec(novtable) MarkImplements<I0, true>
  {
      typedef ImplementsMarker<I0> Type;
  };
  
  template <typename I0>
  struct __declspec(novtable) MarkImplements<CloakedIid<I0>, true>
  {
      // Cloaked Implements type will be handled in the nested processing.
      // Applying the ImplementsMarker too early will bypass Cloaked behavior.
      typedef CloakedIid<I0> Type;
  };
  
  template <typename DerivedType, typename BaseType, bool hasImplements>
  struct __declspec(novtable) MarkImplements<MixIn<DerivedType, BaseType, hasImplements>, true>
  {
      // Implements type in mix-ins will be handled in the nested processing.
      typedef MixIn<DerivedType, BaseType, hasImplements> Type;
  };
  
  // AdjustImplements pre-processes the type list for more efficient builds.
  template <typename RuntimeClassFlagsT, bool doStrictCheck, typename ...Bases>
  struct __declspec(novtable) AdjustImplements;
  
  template <typename RuntimeClassFlagsT, bool doStrictCheck, typename I0, typename ...Bases>
  struct __declspec(novtable) AdjustImplements<RuntimeClassFlagsT, doStrictCheck, I0, Bases...>
  {
      typedef ImplementsHelper<RuntimeClassFlagsT, doStrictCheck, typename MarkImplements<I0, __is_base_of(ImplementsBase, I0)>::Type, Bases...> Type;
  };
  
  // Use AdjustImplements to remove instances of "Details::Nil" from the type list.
  template <typename RuntimeClassFlagsT, bool doStrictCheck, typename ...Bases>
  struct __declspec(novtable) AdjustImplements<RuntimeClassFlagsT, doStrictCheck, typename Details::Nil, Bases...>
  {
      typedef typename AdjustImplements<RuntimeClassFlagsT, doStrictCheck, Bases...>::Type Type;
  };
  
  
  template <typename RuntimeClassFlagsT, bool doStrictCheck>
  struct __declspec(novtable) AdjustImplements<RuntimeClassFlagsT, doStrictCheck>
  {
      typedef ImplementsHelper<RuntimeClassFlagsT, doStrictCheck> Type;
  };
  
  
  // Specialization handles unadorned interfaces
  template <typename RuntimeClassFlagsT, bool doStrictCheck, typename I0, typename ...TInterfaces>
  struct __declspec(novtable) ImplementsHelper<RuntimeClassFlagsT, doStrictCheck, I0, TInterfaces...> :
      I0,
      AdjustImplements<RuntimeClassFlagsT, true, TInterfaces...>::Type
  {
      template <typename RuntimeClassFlagsT, bool doStrictCheck, typename ...TInterfaces> friend struct ImplementsHelper;
      template <unsigned int RuntimeClassTypeT> friend class RuntimeClassBaseT;
  
  protected:
  
      HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv, bool *pRefDelegated = nullptr) throw()
      {
          VerifyInterfaceHelper<RuntimeClassFlagsT::value & WinRtClassicComMix, I0, doStrictCheck>::Verify();
          // Prefer InlineIsEqualGUID over other forms since it's better perf on 4-byte aligned data, which is almost always the case.
          if (InlineIsEqualGUID(riid, __uuidof(I0)))
          {
              *ppv = reinterpret_cast<I0*>(reinterpret_cast<void*>(this));
              return S_OK;
          }
          return AdjustImplements<RuntimeClassFlagsT, true, TInterfaces...>::Type::CanCastTo(riid, ppv, pRefDelegated);
      }
  
      IUnknown* CastToUnknown() throw()
      {
          return reinterpret_cast<I0*>(reinterpret_cast<void*>(this));
      }
  
      unsigned long GetIidCount() throw()
      {
          return 1 + AdjustImplements<RuntimeClassFlagsT, true, TInterfaces...>::Type::GetIidCount();
      }
  
      // FillArrayWithIid
      void FillArrayWithIid(_Inout_ unsigned long *index, _Inout_ IID* iids) throw()
      {
          *(iids + *index) = __uuidof(I0);
          (*index)++;
          AdjustImplements<RuntimeClassFlagsT, true, TInterfaces...>::Type::FillArrayWithIid(index, iids);
      }
  };
  
  
  // Selector is used to "tag" base interfaces to be used in casting, since a runtime class may indirectly derive from 
  // the same interface or Implements<> template multiple times
  template <typename base, typename disciminator>
  struct  __declspec(novtable) Selector : public base
  {
  };
  
  // Specialization handles types that derive from ImplementsHelper (e.g. nested Implements).
  template <typename RuntimeClassFlagsT, bool doStrictCheck, typename I0, typename ...TInterfaces>
  struct __declspec(novtable) ImplementsHelper<RuntimeClassFlagsT, doStrictCheck, ImplementsMarker<I0>, TInterfaces...> :
      Selector<I0, ImplementsHelper<RuntimeClassFlagsT, doStrictCheck, ImplementsMarker<I0>, TInterfaces...>>,
      Selector<typename AdjustImplements<RuntimeClassFlagsT, true, TInterfaces...>::Type, ImplementsHelper<RuntimeClassFlagsT, doStrictCheck, ImplementsMarker<I0>, TInterfaces...>>
  {
      template <typename RuntimeClassFlagsT, bool doStrictCheck, typename ...TInterfaces> friend struct ImplementsHelper;
      template <unsigned int RuntimeClassTypeT> friend class RuntimeClassBaseT;
  
  protected:
      typedef Selector<I0, ImplementsHelper<RuntimeClassFlagsT, doStrictCheck, ImplementsMarker<I0>, TInterfaces...>> CurrentType;
      typedef Selector<typename AdjustImplements<RuntimeClassFlagsT, true, TInterfaces...>::Type, ImplementsHelper<RuntimeClassFlagsT, doStrictCheck, ImplementsMarker<I0>, TInterfaces...>> BaseType;
  
      HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv, bool *pRefDelegated = nullptr) throw()
      {
          VerifyInterfaceHelper<RuntimeClassFlagsT::value & WinRtClassicComMix, I0, doStrictCheck>::Verify();
          HRESULT hr = CurrentType::CanCastTo(riid, ppv);
          if (hr == E_NOINTERFACE)
          {
              hr = BaseType::CanCastTo(riid, ppv, pRefDelegated);
          }
          return hr;
      }
  
      IUnknown* CastToUnknown() throw()
      {
          // First in list wins.
          return CurrentType::CastToUnknown();
      }
  
      unsigned long GetIidCount() throw()
      {
          return CurrentType::GetIidCount() + BaseType::GetIidCount();
      }
  
      // FillArrayWithIid
      void FillArrayWithIid(_Inout_ unsigned long *index, _Inout_ IID* iids) throw()
      {
          CurrentType::FillArrayWithIid(index, iids);
          BaseType::FillArrayWithIid(index, iids);
      }
  };
  
  // CloakedIid instance. Since the first "real" interface should be checked against doStrictCheck, 
  // pass this through unchanged. Two specializations for cloaked prevent the need to use the Selector
  // used in the Implements<> case. The same can't be done there because some type ambiguities are unavoidable.
  template <typename RuntimeClassFlagsT, bool doStrictCheck, typename I0, typename I1, typename ...TInterfaces>
  struct __declspec(novtable) ImplementsHelper<RuntimeClassFlagsT, doStrictCheck, CloakedIid<I0>, I1, TInterfaces...> :
      AdjustImplements<RuntimeClassFlagsT, doStrictCheck, I0>::Type,
      AdjustImplements<RuntimeClassFlagsT, true, I1, TInterfaces...>::Type
  {
      template <typename RuntimeClassFlagsT, bool doStrictCheck, typename ...TInterfaces> friend struct ImplementsHelper;
      template <unsigned int RuntimeClassTypeT> friend class Details::RuntimeClassBaseT;
  
  protected:
  
      typedef typename AdjustImplements<RuntimeClassFlagsT, doStrictCheck, I0>::Type CurrentType;
      typedef typename AdjustImplements<RuntimeClassFlagsT, true, I1, TInterfaces...>::Type BaseType;
  
      HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv, bool *pRefDelegated = nullptr) throw()
      {
          VerifyInterfaceHelper<RuntimeClassFlagsT::value & WinRtClassicComMix, I0, doStrictCheck>::Verify();
  
          HRESULT hr = CurrentType::CanCastTo(riid, ppv, pRefDelegated);
          if (SUCCEEDED(hr))
          {
              return S_OK;
          }
          return BaseType::CanCastTo(riid, ppv, pRefDelegated);
      }
  
      IUnknown* CastToUnknown() throw()
      {
          return CurrentType::CastToUnknown();
      }
  
      // Don't expose the cloaked IID(s), but continue processing the rest of the interfaces
      unsigned long GetIidCount() throw()
      {
          return BaseType::GetIidCount();
      }
  
      void FillArrayWithIid(_Inout_ unsigned long *index, _Inout_ IID* iids) throw()
      {
          BaseType::FillArrayWithIid(index, iids);
      }
  };
  
  template <typename RuntimeClassFlagsT, bool doStrictCheck, typename I0>
  struct __declspec(novtable) ImplementsHelper<RuntimeClassFlagsT, doStrictCheck, CloakedIid<I0>> :
      AdjustImplements<RuntimeClassFlagsT, doStrictCheck, I0>::Type
  {
      template <typename RuntimeClassFlagsT, bool doStrictCheck, typename ...TInterfaces> friend struct ImplementsHelper;
      template <unsigned int RuntimeClassTypeT> friend class Details::RuntimeClassBaseT;
  
  protected:
  
      typedef typename AdjustImplements<RuntimeClassFlagsT, doStrictCheck, I0>::Type CurrentType;
  
      HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv, bool *pRefDelegated = nullptr) throw()
      {
          VerifyInterfaceHelper<RuntimeClassFlagsT::value & WinRtClassicComMix, I0, doStrictCheck>::Verify();
  
          return CurrentType::CanCastTo(riid, ppv, pRefDelegated);
      }
  
      IUnknown* CastToUnknown() throw()
      {
          return CurrentType::CastToUnknown();
      }
  
      // Don't expose the cloaked IID(s), but continue processing the rest of the interfaces
      unsigned long GetIidCount() throw()
      {
          return 0;
      }
  
      void FillArrayWithIid(_Inout_ unsigned long * /*index*/, _Inout_ IID* /*iids*/) throw()
      {
          // no-op
      }
  };
  
  
  // terminal case specialization.
  template <typename RuntimeClassFlagsT, bool doStrictCheck>
  struct __declspec(novtable) ImplementsHelper<RuntimeClassFlagsT, doStrictCheck>
  {
      template <typename RuntimeClassFlagsT, bool doStrictCheck, typename ...TInterfaces> friend struct ImplementsHelper;
      template <unsigned int RuntimeClassTypeT> friend class RuntimeClassBaseT;
  
  protected:
      template <unsigned int RuntimeClassTypeT> friend class Details::RuntimeClassBaseT;    
  
      HRESULT CanCastTo(_In_ REFIID /*riid*/, _Outptr_ void ** /*ppv*/, bool * /*pRefDelegated*/ = nullptr) throw()
      {
          return E_NOINTERFACE;
      }
  
      // IUnknown* CastToUnknown() throw(); // not defined for terminal case.
  
      unsigned long GetIidCount() throw()
      {
          return 0;
      }
  
      void FillArrayWithIid(_Inout_ unsigned long * /*index*/, _Inout_ IID* /*iids*/) throw()
      {
      }
  };
  
  // Specialization handles chaining interfaces
  template <typename RuntimeClassFlagsT, bool doStrictCheck, typename C0, typename C1, typename C2, typename C3, typename C4, typename C5, typename C6, typename C7, typename C8, typename C9, typename ...TInterfaces>
  struct __declspec(novtable) ImplementsHelper<RuntimeClassFlagsT, doStrictCheck, ChainInterfaces<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9>, TInterfaces...> :
      ChainInterfaces<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9>,
      AdjustImplements<RuntimeClassFlagsT, true, TInterfaces...>::Type
  {
      template <typename RuntimeClassFlagsT, bool doStrictCheck, typename ...TInterfaces> friend struct ImplementsHelper;
      template <unsigned int RuntimeClassTypeT> friend class RuntimeClassBaseT;
  
  protected:
      template <unsigned int RuntimeClassTypeT> friend class Details::RuntimeClassBaseT;    
      typedef typename AdjustImplements<RuntimeClassFlagsT, true, TInterfaces...>::Type BaseType;
  
      HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv, bool *pRefDelegated = nullptr) throw()
      {
          ChainInterfaces<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9>::template Verify<RuntimeClassFlagsT::value>();
          
          HRESULT hr = ChainInterfaces<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9>::CanCastTo(riid, ppv);
          if (FAILED(hr))
          {
              hr = BaseType::CanCastTo(riid, ppv, pRefDelegated);
          }
  
          return hr;
      }
  
      IUnknown* CastToUnknown() throw()
      {
          return ChainInterfaces<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9>::CastToUnknown();
      }
  
      unsigned long GetIidCount() throw()
      {
          return ChainInterfaces<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9>::IidCount + BaseType::GetIidCount();
      }
  
      void FillArrayWithIid(_Inout_ unsigned long *index, _Inout_ IID* iids) throw()
      {
          ChainInterfaces<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9>::FillArrayWithIid(index, iids);
          BaseType::FillArrayWithIid(index, iids);
      }
  };
  
  
  // Mixin specialization
  template <typename RuntimeClassFlagsT, typename DerivedType, typename BaseMixInType, bool hasImplements, typename ...TInterfaces, bool doStrictCheck>
  struct __declspec(novtable) ImplementsHelper<RuntimeClassFlagsT, doStrictCheck, MixIn<DerivedType, BaseMixInType, hasImplements>, TInterfaces...> :
      AdjustImplements<RuntimeClassFlagsT, true, TInterfaces...>::Type
  {
      static_assert(hasImplements, "Cannot use MixIn to with a class not deriving from \"Implements\"");
  
      template <typename RuntimeClassFlagsT, bool doStrictCheck, typename ...TInterfaces> friend struct ImplementsHelper;
      template <unsigned int RuntimeClassTypeT> friend class RuntimeClassBaseT;
  
  protected:
      template <unsigned int RuntimeClassTypeT> friend class Details::RuntimeClassBaseT;
      typedef typename AdjustImplements<RuntimeClassFlagsT, true, TInterfaces...>::Type BaseType;
  
      HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv, bool *pRefDelegated = nullptr) throw()
      {
          VerifyInterfaceHelper<RuntimeClassFlagsT::value & WinRtClassicComMix, BaseMixInType, doStrictCheck>::Verify();
          
          HRESULT hr = static_cast<BaseMixInType*>(static_cast<DerivedType*>(this))->CanCastTo(riid, ppv);
          if (FAILED(hr))
          {
              hr = BaseType::CanCastTo(riid, ppv, pRefDelegated);
          }
  
          return hr;            
      }
  
      IUnknown* CastToUnknown() throw()
      {
          return static_cast<BaseMixInType*>(static_cast<DerivedType*>(this))->CastToUnknown();
      }
  
      unsigned long GetIidCount() throw()
      {
          return static_cast<BaseMixInType*>(static_cast<DerivedType*>(this))->GetIidCount() +
              BaseType::GetIidCount();
      }
  
      void FillArrayWithIid(_Inout_ unsigned long *index, _Inout_ IID* iids) throw()
      {
          static_cast<BaseMixInType*>(static_cast<DerivedType*>(this))->FillArrayWithIid(index, iids);
          BaseType::FillArrayWithIid(index, iids);
      }
  };
  
  // Specialization handles inheriting COM objects. ComposableBase must be the last non-nil interface in the list.
  // Trailing nil's are allowed for compatibility with some tools that pad out the list.
  template <typename I0, typename ...>
  struct AreAllNil
  {
      static const bool value = false;
  };
  
  template <typename ...TInterfaces>
  struct AreAllNil<Microsoft::WRL::Details::Nil, TInterfaces...>
  {
      static const bool value = AreAllNil<TInterfaces...>::value;
  };
  
  template <>
  struct AreAllNil<Microsoft::WRL::Details::Nil>
  {
      static const bool value = true;
  };
  
  template <typename RuntimeClassFlagsT, typename FactoryInterface, bool doStrictCheck, typename ...TInterfaces>
  struct __declspec(novtable) ImplementsHelper<RuntimeClassFlagsT, doStrictCheck, ComposableBase<FactoryInterface>, TInterfaces...> :
      ImplementsHelper<RuntimeClassFlagsT, true, ComposableBase<FactoryInterface>>
  {
      template <typename RuntimeClassFlagsT, bool doStrictCheck, typename ...TInterfaces> friend struct ImplementsHelper;
      template <unsigned int RuntimeClassTypeT> friend class RuntimeClassBaseT;
  
  protected:
      template <unsigned int RuntimeClassTypeT> friend class Details::RuntimeClassBaseT;
  
      typedef ImplementsHelper<RuntimeClassFlagsT, true, ComposableBase<FactoryInterface>> BaseType;
  
      HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv, bool *pRefDelegated = nullptr) throw()
      {
          static_assert(AreAllNil<TInterfaces...>::value, "ComposableBase should be the last template parameter to RuntimeClass");
          return BaseType::CanCastTo(riid, ppv, pRefDelegated);
      }
  
      IUnknown* CastToUnknown() throw()
      {
          static_assert(AreAllNil<TInterfaces...>::value, "ComposableBase should be the last template parameter to RuntimeClass");
          return BaseType::CastToUnknown();
      }
  
      unsigned long GetIidCount() throw()
      {
          static_assert(AreAllNil<TInterfaces...>::value, "ComposableBase should be the last template parameter to RuntimeClass");
          return BaseType::GetIidCount();
      }
  
      void FillArrayWithIid(_Inout_ unsigned long *index, _Inout_ IID* iids) throw()
      {
          static_assert(AreAllNil<TInterfaces...>::value, "ComposableBase should be the last template parameter to RuntimeClass");
          BaseType::FillArrayWithIid(index, iids);
      }
  };
  
  template <typename RuntimeClassFlagsT, typename FactoryInterface, bool doStrictCheck>
  struct __declspec(novtable) ImplementsHelper<RuntimeClassFlagsT, doStrictCheck, ComposableBase<FactoryInterface>>
  {
      template <typename RuntimeClassFlagsT, bool doStrictCheck, typename ...TInterfaces> friend struct ImplementsHelper;
      template <unsigned int RuntimeClassTypeT> friend class RuntimeClassBaseT;
  
  protected:
      template <unsigned int RuntimeClassTypeT> friend class Details::RuntimeClassBaseT;
  
      HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv, bool *pRefDelegated) throw()
      {
          *pRefDelegated = true;
          return composableBase_.CopyTo(riid, ppv);
      }
  
      IUnknown* CastToUnknown() throw()
      {
          return nullptr;
      }
  
      unsigned long GetIidCount() throw()
      {
          return iidCount_;
      }
  
      void FillArrayWithIid(_Inout_ unsigned long *index, _Inout_ IID* iids) throw()
      {
          for(unsigned long i = 0; i < iidCount_; i++)
          {
              *(iids + *index) = *(iidsCached_ + i);
              (*index)++;
          }
      }
  
      ImplementsHelper() throw() : iidsCached_(nullptr), iidCount_(0)
      {
      }
  
      ~ImplementsHelper() throw()
      {
          ::CoTaskMemFree(iidsCached_);
          iidsCached_ = nullptr;
          iidCount_ = 0;
      }
  
  public:
      HRESULT SetComposableBasePointers(_In_ IInspectable* base, _In_opt_ FactoryInterface* baseFactory = nullptr) throw()
      {
          if (composableBase_ != nullptr)
          {
  #if (NTDDI_VERSION >= NTDDI_WINBLUE)
              ErrorHelper<RuntimeClassFlagsT::value & InhibitRoOriginateError>::OriginateError(E_UNEXPECTED, nullptr);
  #endif // (NTDDI_VERSION >= NTDDI_WINBLUE)
              return E_UNEXPECTED;
          }
  
          HRESULT hr = base->GetIids(&iidCount_, &iidsCached_);
          if (SUCCEEDED(hr))
          {
              composableBase_ = base;
              composableBaseFactory_ = baseFactory;
          }
          return hr;
      }
  
      ComPtr<IInspectable> GetComposableBase() throw()
      {
          return composableBase_;
      }
  
      ComPtr<FactoryInterface> GetComposableBaseFactory() throw()
      {
          return composableBaseFactory_;
      }
  
  private:
      ComPtr<IInspectable> composableBase_;
      ComPtr<FactoryInterface> composableBaseFactory_;
      IID *iidsCached_;
      unsigned long iidCount_;
  };
  
  #pragma endregion // Implements helper templates
  
  } // namespace Details
  
  // Implements - template implementing QI using the information provided through its template parameters
  // Each template parameter has to be one of the following:
  // * COM Interface
  // * A class that implements one or more COM interfaces
  // * ChainInterfaces template
  template <typename I0, typename ...TInterfaces>
  struct __declspec(novtable) Implements :
      Details::AdjustImplements<RuntimeClassFlags<WinRt>, true, I0, TInterfaces...>::Type,
      Details::ImplementsBase
  {
  public:
      typedef RuntimeClassFlags<WinRt> ClassFlags;
      typedef I0 FirstInterface;
  protected:
      typedef typename Details::AdjustImplements<RuntimeClassFlags<WinRt>, true, I0, TInterfaces...>::Type BaseType;
      template <typename RuntimeClassFlagsT, bool doStrictCheck, typename ...TInterfaces> friend struct Details::ImplementsHelper;
      template <unsigned int RuntimeClassTypeT> friend class Details::RuntimeClassBaseT;
  
      HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv) throw()
      {
          return BaseType::CanCastTo(riid, ppv);
      }
  
      IUnknown* CastToUnknown() throw()
      {
          return BaseType::CastToUnknown();
      }
  
      unsigned long GetIidCount() throw()
      {
          return BaseType::GetIidCount();
      }
  
      void FillArrayWithIid(_Inout_ unsigned long *index, _Inout_ IID* iids) throw()
      {
          BaseType::FillArrayWithIid(index, iids);
      }
  };
  
  template <int flags, typename I0, typename ...TInterfaces>
  struct __declspec(novtable) Implements<RuntimeClassFlags<flags>, I0, TInterfaces...> :
      Details::AdjustImplements<RuntimeClassFlags<flags>, true, I0, TInterfaces...>::Type,
      Details::ImplementsBase
  {
  public:
      typedef RuntimeClassFlags<flags> ClassFlags;
      typedef I0 FirstInterface;
  protected:
  
      typedef typename Details::AdjustImplements<RuntimeClassFlags<flags>, true, I0, TInterfaces...>::Type BaseType;
      template <typename RuntimeClassFlagsT, bool doStrictCheck, typename ...TInterfaces> friend struct Details::ImplementsHelper;
      template <unsigned int RuntimeClassTypeT> friend class Details::RuntimeClassBaseT;    
  
      HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv) throw()
      {
          return BaseType::CanCastTo(riid, ppv);
      }
  
      IUnknown* CastToUnknown() throw()
      {
          return BaseType::CastToUnknown();
      }
  
      unsigned long GetIidCount() throw()
      {
          return BaseType::GetIidCount();
      }
  
      void FillArrayWithIid(_Inout_ unsigned long *index, _Inout_ IID* iids) throw()
      {
          BaseType::FillArrayWithIid(index, iids);
      }
  };
  
  class FtmBase : 
      public Implements< 
          ::Microsoft::WRL::RuntimeClassFlags<WinRtClassicComMix>, 
          ::Microsoft::WRL::CloakedIid< ::IMarshal> >,
      // Inheriting from FtmBaseMarker allows using FtmBase on classes configured with RuntimeClassFlags<WinRt> (Default configuration)
      private ::Microsoft::WRL::Details::FtmBaseMarker
  {
      // defining type 'Super' for other compilers since '__super' is a VC++-specific language extension
      using Super = Implements< 
        ::Microsoft::WRL::RuntimeClassFlags<WinRtClassicComMix>, 
        ::Microsoft::WRL::CloakedIid< ::IMarshal> >;
  protected:
      template <typename RuntimeClassFlagsT, bool doStrictCheck, typename ...TInterfaces> friend struct Details::ImplementsHelper;
  
      HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv) throw()
      {
          // Prefer InlineIsEqualGUID over other forms since it's better perf on 4-byte aligned data, which is almost always the case.
          if (InlineIsEqualGUID(riid, __uuidof(::IAgileObject)))
          {
              
              *ppv = Super::CastToUnknown();
              return S_OK;
          }
  
          return Super::CanCastTo(riid, ppv);
      }
  
  public:
      FtmBase() throw()
      {
          ComPtr<IUnknown> unknown;
          if (SUCCEEDED(::CoCreateFreeThreadedMarshaler(nullptr, &unknown)))
          {
              unknown.As(&marshaller_);
          }
      }
  
      // IMarshal Methods
  #pragma warning(suppress: 6101) // PREFast cannot see through the smart-pointer invocation
      STDMETHOD(GetUnmarshalClass)(_In_ REFIID riid,
                                     _In_opt_ void *pv,
                                     _In_ DWORD dwDestContext,
                                     _Reserved_ void *pvDestContext,
                                     _In_ DWORD mshlflags,
                                     _Out_ CLSID *pCid) override
      {
          if (marshaller_)
          {
              return marshaller_->GetUnmarshalClass(riid, pv, dwDestContext, pvDestContext, mshlflags, pCid);
          }
          return E_OUTOFMEMORY;
      }
  
  #pragma warning(suppress: 6101) // PREFast cannot see through the smart-pointer invocation
      STDMETHOD(GetMarshalSizeMax)(_In_ REFIID riid, _In_opt_ void *pv, _In_ DWORD dwDestContext,
                                     _Reserved_ void *pvDestContext, _In_ DWORD mshlflags, _Out_ DWORD *pSize) override
      {
          if (marshaller_)
          {
              return marshaller_->GetMarshalSizeMax(riid, pv, dwDestContext, pvDestContext, mshlflags, pSize);
          }
          return E_OUTOFMEMORY;
      }
  
      STDMETHOD(MarshalInterface)(_In_ IStream *pStm, _In_ REFIID riid, _In_opt_ void *pv, _In_ DWORD dwDestContext,
                                    _Reserved_ void *pvDestContext, _In_ DWORD mshlflags) override
      {
          if (marshaller_)
          {
              return marshaller_->MarshalInterface(pStm, riid, pv, dwDestContext, pvDestContext, mshlflags);
          }
          return E_OUTOFMEMORY;
      }
  
  #pragma warning(suppress: 6101) // PREFast cannot see through the smart-pointer invocation
      STDMETHOD(UnmarshalInterface)(_In_ IStream *pStm, _In_ REFIID riid, _Outptr_ void **ppv) override
      {
          if (marshaller_)
          {
              return marshaller_->UnmarshalInterface(pStm, riid, ppv);
          }
          return E_OUTOFMEMORY;
      }
  
      STDMETHOD(ReleaseMarshalData)(_In_ IStream *pStm) override
      {
          if (marshaller_)
          {
              return marshaller_->ReleaseMarshalData(pStm);
          }
          return E_OUTOFMEMORY;
      }
  
      STDMETHOD(DisconnectObject)(_In_ DWORD dwReserved) override
      {
          if (marshaller_)
          {
              return marshaller_->DisconnectObject(dwReserved);
          }
          return E_OUTOFMEMORY;
      }
  
      static HRESULT CreateGlobalInterfaceTable(_Out_ IGlobalInterfaceTable **git) throw()
      {
          *git = nullptr;
          return ::CoCreateInstance(CLSID_StdGlobalInterfaceTable,
              nullptr,
              CLSCTX_INPROC_SERVER,
              __uuidof(IGlobalInterfaceTable),
              reinterpret_cast<void**>(git));
      }
  
      ::Microsoft::WRL::ComPtr<IMarshal> marshaller_;  // Holds a reference to the free threaded marshaler
  };
  
  namespace Details
  {
  
  #ifdef _PERF_COUNTERS
  class __declspec(novtable) PerfCountersBase
  {
  public:
      ULONG GetAddRefCount() throw()
      {
          return addRefCount_;
      }
  
      ULONG GetReleaseCount() throw()
      {
          return releaseCount_;
      }
  
      ULONG GetQueryInterfaceCount() throw()
      {
          return queryInterfaceCount_;
      }
  
      void ResetPerfCounters() throw()
      {
          addRefCount_ = 0;
          releaseCount_ = 0;
          queryInterfaceCount_ = 0;
      }
  
  protected:
      PerfCountersBase() throw() : 
          addRefCount_(0),
          releaseCount_(0),
          queryInterfaceCount_(0)
      {
      }
  
      void IncrementAddRefCount() throw()
      {
          InterlockedIncrement(&addRefCount_);
      }
  
      void IncrementReleaseCount() throw()
      {
          InterlockedIncrement(&releaseCount_);
      }
  
      void IncrementQueryInterfaceCount() throw()
      {
          InterlockedIncrement(&queryInterfaceCount_);
      }
  
  private:
      volatile unsigned long addRefCount_;
      volatile unsigned long releaseCount_;
      volatile unsigned long queryInterfaceCount_;
  };
  #endif
  
  #if defined(_X86_) || defined(_AMD64_)
  
  #define UnknownIncrementReference InterlockedIncrement
  #define UnknownDecrementReference InterlockedDecrement
  #define UnknownBarrierAfterInterlock() 
  #define UnknownInterlockedCompareExchangePointer InterlockedCompareExchangePointer
  #define UnknownInterlockedCompareExchangePointerForIncrement InterlockedCompareExchangePointer
  #define UnknownInterlockedCompareExchangePointerForRelease InterlockedCompareExchangePointer
  
  #elif defined(_ARM_)
  
  #define UnknownIncrementReference InterlockedIncrementNoFence
  #define UnknownDecrementReference InterlockedDecrementRelease
  #define UnknownBarrierAfterInterlock() __dmb(_ARM_BARRIER_ISH)
  #define UnknownInterlockedCompareExchangePointer InterlockedCompareExchangePointer
  #define UnknownInterlockedCompareExchangePointerForIncrement InterlockedCompareExchangePointerNoFence
  #define UnknownInterlockedCompareExchangePointerForRelease InterlockedCompareExchangePointerRelease
  
  #elif defined(_ARM64_)
  
  #define UnknownIncrementReference InterlockedIncrementNoFence
  #define UnknownDecrementReference InterlockedDecrementRelease
  #define UnknownBarrierAfterInterlock() __dmb(_ARM64_BARRIER_ISH)
  #define UnknownInterlockedCompareExchangePointer InterlockedCompareExchangePointer
  #define UnknownInterlockedCompareExchangePointerForIncrement InterlockedCompareExchangePointerNoFence
  #define UnknownInterlockedCompareExchangePointerForRelease InterlockedCompareExchangePointerRelease
  
  #else
  
  #error Unsupported architecture.
  
  #endif
  
  // Since variadic templates can't have a parameter pack after default arguments, provide a convenient helper for defaults.
  #define DETAILS_RTCLASS_FLAGS_ARGUMENTS(RuntimeClassFlagsT) \
      RuntimeClassFlagsT, \
      (RuntimeClassFlagsT::value & InhibitWeakReference) == 0, \
      (RuntimeClassFlagsT::value & WinRt) == WinRt, \
      __WRL_IMPLEMENTS_FTM_BASE__(RuntimeClassFlagsT::value) \
  
  template <class RuntimeClassFlagsT, bool implementsWeakReferenceSource, bool implementsInspectable, bool implementsFtmBase, typename ...TInterfaces>
  class __declspec(novtable) RuntimeClassImpl;
  
  #pragma warning(push)
  // PREFast cannot see through template instantiation for AsIID() 
  #pragma warning(disable: 6388)
  
  template <class RuntimeClassFlagsT, bool implementsWeakReferenceSource, bool implementsFtmBase, typename ...TInterfaces>
  class __declspec(novtable) RuntimeClassImpl<RuntimeClassFlagsT, implementsWeakReferenceSource, false, implementsFtmBase, TInterfaces...> :
      public Details::AdjustImplements<RuntimeClassFlagsT, false, TInterfaces...>::Type,
      public RuntimeClassBaseT<RuntimeClassFlagsT::value>,
      protected RuntimeClassFlags<InhibitWeakReference>,
      public DontUseNewUseMake
  #ifdef _PERF_COUNTERS
      , public PerfCountersBase
  #endif
  {
  public:
      typedef RuntimeClassFlagsT ClassFlags;
  
      STDMETHOD(QueryInterface)(REFIID riid, _Outptr_result_nullonfailure_ void **ppvObject)
      {
  #ifdef _PERF_COUNTERS
          IncrementQueryInterfaceCount();
  #endif
          return Super::AsIID(this, riid, ppvObject);
      }
  
      STDMETHOD_(ULONG, AddRef)()
      {
          return InternalAddRef();
      }
  
      STDMETHOD_(ULONG, Release)()    
      {
          ULONG ref = InternalRelease();
          if (ref == 0)
          {
              delete this;
  
              auto modulePtr = ::Microsoft::WRL::GetModuleBase();
              if (modulePtr != nullptr)
              {
                  modulePtr->DecrementObjectCount();
              }
          }
  
          return ref;
      }
  
  protected:
      using Super = RuntimeClassBaseT<RuntimeClassFlagsT::value>;
  
      RuntimeClassImpl() throw() : refcount_(1)
      {
      }    
  
      virtual ~RuntimeClassImpl() throw()
      {
          // Set refcount_ to -(LONG_MAX/2) to protect destruction and
          // also catch mismatched Release in debug builds
          refcount_ = -(LONG_MAX/2);
      }
  
      unsigned long InternalAddRef() throw()
      {
  #ifdef _PERF_COUNTERS
          IncrementAddRefCount();
  #endif
          return UnknownIncrementReference(&refcount_);
      }
  
      unsigned long InternalRelease() throw()
      {
  #ifdef _PERF_COUNTERS
          IncrementReleaseCount();
  #endif
          // A release fence is required to ensure all guarded memory accesses are
          // complete before any thread can begin destroying the object.
          unsigned long newValue = UnknownDecrementReference(&refcount_);
          if (newValue == 0)
          {
              // An acquire fence is required before object destruction to ensure
              // that the destructor cannot observe values changing on other threads.
              UnknownBarrierAfterInterlock();
          }
          return newValue;
      }
  
      unsigned long GetRefCount() const throw()
      {
          return refcount_;
      }
  
      friend class WeakReferenceImpl;
  
  private:
      volatile long refcount_;
  };
  
  template<typename I, bool isImplementsBased = __is_base_of(ImplementsBase, I)>
  struct HasIInspectable;
  
  template<typename I>
  struct HasIInspectable<I, false>
  {
      static const bool isIInspectable = __is_base_of(IInspectable, I);
  };
  
  template<typename I>
  struct HasIInspectable<I, true>
  {
      static const bool isIInspectable = HasIInspectable<typename I::FirstInterface>::isIInspectable;
  };
  
  #ifdef __WRL_STRICT__
  template<typename I0, bool isIInspectable = true>
  #else
  template<typename I0, bool isIInspectable = HasIInspectable<I0>::isIInspectable>
  #endif
  struct IInspectableInjector;
  
  template<typename I0>
  struct IInspectableInjector<I0, true>
  {
      typedef Details::Nil InspectableIfNeeded;
  };
  
  template<typename I0>
  struct IInspectableInjector<I0, false>
  {
      typedef IInspectable InspectableIfNeeded;
  };
  
  // Implements IInspectable in ILst
  template <class RuntimeClassFlagsT, typename I0, typename ...TInterfaces>
  class __declspec(novtable) RuntimeClassImpl<RuntimeClassFlagsT, false, true, false, I0, TInterfaces...> :
      public Details::AdjustImplements<RuntimeClassFlagsT, false, typename IInspectableInjector<I0>::InspectableIfNeeded, I0, TInterfaces...>::Type,
      public RuntimeClassBaseT<RuntimeClassFlagsT::value>,
      protected RuntimeClassFlags<InhibitWeakReference>,
      public DontUseNewUseMake
  #ifdef _PERF_COUNTERS
      , public PerfCountersBase
  #endif
  {
  public:
      typedef RuntimeClassFlagsT ClassFlags;
  
      STDMETHOD(QueryInterface)(REFIID riid, _Outptr_result_nullonfailure_ void **ppvObject)
      {
  #ifdef _PERF_COUNTERS
          IncrementQueryInterfaceCount();
  #endif
          return Super::AsIID(this, riid, ppvObject);
      }
  
      STDMETHOD_(ULONG, AddRef)()
      {
          return InternalAddRef();
      }
  
      STDMETHOD_(ULONG, Release)()    
      {
          ULONG ref = InternalRelease();
          if (ref == 0)
          {
              delete this;
  
              auto modulePtr = ::Microsoft::WRL::GetModuleBase();
              if (modulePtr != nullptr)
              {
                  modulePtr->DecrementObjectCount();
              }
          }
  
          return ref;
      }
  
      // IInspectable methods
      STDMETHOD(GetIids)(
          _Out_ ULONG *iidCount,
          _When_(*iidCount == 0, _At_(*iids, _Post_null_))
          _When_(*iidCount > 0, _At_(*iids, _Post_notnull_))
          _Result_nullonfailure_ IID **iids)
      {
          return Super::GetImplementedIIDS(this, iidCount, iids);
      }
  
  #if !defined(__WRL_STRICT__) || !defined(__WRL_FORCE_INSPECTABLE_CLASS_MACRO__)
      STDMETHOD(GetRuntimeClassName)(_Out_ HSTRING* runtimeClassName)
      {
          *runtimeClassName = nullptr;
  
          __WRL_ASSERT__(false && "Use InspectableClass macro to set runtime class name and trust level.");
  
  #if (NTDDI_VERSION >= NTDDI_WINBLUE)
          ErrorHelper<RuntimeClassFlagsT::value & InhibitRoOriginateError>::OriginateError(E_NOTIMPL, nullptr);
  #endif // (NTDDI_VERSION >= NTDDI_WINBLUE)
          return E_NOTIMPL;
      }
  
      STDMETHOD(GetTrustLevel)(_Out_ TrustLevel*)
      {
          __WRL_ASSERT__(false && "Use InspectableClass macro to set runtime class name and trust level.");
  
  #if (NTDDI_VERSION >= NTDDI_WINBLUE)
          ErrorHelper<RuntimeClassFlagsT::value & InhibitRoOriginateError>::OriginateError(E_NOTIMPL, nullptr);
  #endif // (NTDDI_VERSION >= NTDDI_WINBLUE)
          return E_NOTIMPL;
      }
  #endif // !defined(__WRL_STRICT__) || !defined(__WRL_FORCE_INSPECTABLE_CLASS_MACRO__)
  
  protected:
      using Super = RuntimeClassBaseT<RuntimeClassFlagsT::value>;
  
      RuntimeClassImpl() throw() : refcount_(1)
      {
      }
  
      virtual ~RuntimeClassImpl() throw()
      {
          // Set refcount_ to -(LONG_MAX/2) to protect destruction and
          // also catch mismatched Release in debug builds
          refcount_ = -(LONG_MAX/2);
      }
  
      unsigned long InternalAddRef() throw()
      {
  #ifdef _PERF_COUNTERS
          IncrementAddRefCount();
  #endif
          return UnknownIncrementReference(&refcount_);
      }
  
      unsigned long InternalRelease() throw()
      {
  #ifdef _PERF_COUNTERS
          IncrementReleaseCount();
  #endif
          // A release fence is required to ensure all guarded memory accesses are
          // complete before any thread can begin destroying the object.
          unsigned long newValue = UnknownDecrementReference(&refcount_);
          if (newValue == 0)
          {
              // An acquire fence is required before object destruction to ensure
              // that the destructor cannot observe values changing on other threads.
              UnknownBarrierAfterInterlock();
          }
          return newValue;
      }
  
      unsigned long GetRefCount() const throw()
      {
          return refcount_;
      }
  private:
      volatile long refcount_;
  };
  
  class StrongReference
  {
  public:
      StrongReference(long refCount = 1) throw() : strongRefCount_(refCount) {}
  
      ~StrongReference() throw()
      {
          // Set refcount_ to -(LONG_MAX/2) to protect destruction and
          // also catch mismatched Release in debug builds
          strongRefCount_ = -(LONG_MAX / 2);
      }
  
      unsigned long IncrementStrongReference() throw()
      {
          return UnknownIncrementReference(&strongRefCount_);
      }
  
      unsigned long DecrementStrongReference() throw()
      {
          // A release fence is required to ensure all guarded memory accesses are
          // complete before any thread can begin destroying the object.
          unsigned long newValue = UnknownDecrementReference(&strongRefCount_);
          if (newValue == 0)
          {
              // An acquire fence is required before object destruction to ensure
              // that the destructor cannot observe values changing on other threads.
              UnknownBarrierAfterInterlock();
          }
          return newValue;
      }
  
      unsigned long GetStrongReferenceCount() throw()
      {
          return strongRefCount_;
      }
  
      void SetStrongReference(unsigned long value) throw()
      {
          strongRefCount_ = value;
      }
  
      long strongRefCount_;
  };
  
  // To support storing, encoding and decoding reference-count/pointers regardless of the target platform.
  // In a RuntimeClass, the refCount_ member can mean either
  //    1. actual reference count
  //    2. pointer to the weak reference object which holds the strong count
  // The member
  //    1. If it is a count, the most significant bit will be OFF
  //    2. If it is an encoded pointer to the weak reference, the most significant bit will be turned ON
  // To test which mode it is
  //    1. Test for negative
  //    2. If it is, it is an encoded pointer to the weak reference
  //    3. If it is not, it is the actual reference count
  // To yield the encoded pointer
  //    1. Test the value for negative 
  //    2. If it is, shift the value to the left and cast it to a WeakReferenceImpl*
  // 
  const UINT_PTR EncodeWeakReferencePointerFlag = static_cast<UINT_PTR>(1) << ((sizeof(UINT_PTR) * 8) - 1);
  
  union ReferenceCountOrWeakReferencePointer
  {
      // Represents the count when it is a count (in practice only the least significant 4 bytes)
      UINT_PTR refCount;
      // Pointer size, *signed* to help with ease of casting and such
      INT_PTR rawValue;
      // The hint that this could also be a pointer
      void* ifHighBitIsSetThenShiftLeftToYieldPointerToWeakReference;
  };
  
  // Helper methods to test, decode and decode the different representations of ReferenceCountOrWeakReferencePointer
  inline bool IsValueAPointerToWeakReference(INT_PTR value)
  {
      return value < 0;
  }
  
  // Forward declaration
  class WeakReferenceImpl;
  inline INT_PTR EncodeWeakReferencePointer(Microsoft::WRL::Details::WeakReferenceImpl* value);
  inline Microsoft::WRL::Details::WeakReferenceImpl* DecodeWeakReferencePointer(INT_PTR value);
  
  // Helper functions, originally from winnt.h, needed to get the semantics right when fetching values
  // in multi-threaded scenarios. This is in order to guarantee the compiler emits exactly one read
  // (compiler may decide to re-fetch the value later on, which in some cases can break code)
  #if defined(_ARM_)
  
  FORCEINLINE
  LONG
  ReadULongPtrNoFence (
      _In_ _Interlocked_operand_ DWORD const volatile *Source
      )
  
  {
      LONG Value;
  
      Value = __iso_volatile_load32((int *)Source);
      return Value;
  }
  
  #elif defined(_ARM64_)
  
  FORCEINLINE
  LONG64
  ReadULongPtrNoFence (
      _In_ _Interlocked_operand_ DWORD64 const volatile *Source
      )
  
  {
      LONG64 Value;
  
      Value = __iso_volatile_load64((__int64 *)Source);
      return Value;
  }
  
  #elif defined(_X86_)
  
  FORCEINLINE
  LONG
  ReadULongPtrNoFence (
      _In_ _Interlocked_operand_ DWORD const volatile *Source
      )
  
  {
      LONG Value;
  
      Value = *Source;
      return Value;
  }
  
  #elif defined(_AMD64_)
  
  FORCEINLINE
  LONG64
  ReadULongPtrNoFence (
      _In_ _Interlocked_operand_ DWORD64 const volatile *Source
      )
  
  {
      LONG64 Value;
  
      Value = *Source;
      return Value;
  }
  
  #else
  
  #error Unsupported architecture.
  
  #endif
  
  template <typename T>
  inline T ReadValueFromPointerNoFence(_In_ const volatile T* value)
  {
      ULONG_PTR currentValue = ReadULongPtrNoFence(reinterpret_cast<const volatile ULONG_PTR *>(value));
      const T* currentPointerToValue = reinterpret_cast<T*>(&currentValue);
      return *currentPointerToValue;
  }
  
  inline WeakReferenceImpl* CreateWeakReference(_In_ IUnknown*);
  
  // Implementation of activatable class that implements IWeakReferenceSource
  // and delegates reference counting to WeakReferenceImpl object
  template <class RuntimeClassFlagsT, typename I0, typename ...TInterfaces>
  class __declspec(novtable) RuntimeClassImpl<RuntimeClassFlagsT, true, true, false, I0, TInterfaces...> :
      public Details::AdjustImplements<RuntimeClassFlagsT, false, typename IInspectableInjector<I0>::InspectableIfNeeded, I0, IWeakReferenceSource, TInterfaces...>::Type,
      public RuntimeClassBaseT<RuntimeClassFlagsT::value>,
      public DontUseNewUseMake
  #ifdef _PERF_COUNTERS
      , public PerfCountersBase
  #endif
  {
  public:
      typedef RuntimeClassFlagsT ClassFlags;
  
      RuntimeClassImpl() throw()
      {
          refCount_.rawValue = 1;
      }
  
      STDMETHOD(QueryInterface)(REFIID riid, _Outptr_result_nullonfailure_ void **ppvObject)
      {
  #ifdef _PERF_COUNTERS
          IncrementQueryInterfaceCount();
  #endif
          return Super::AsIID(this, riid, ppvObject);
      }
  
      STDMETHOD_(ULONG, AddRef)()
      {
          return InternalAddRef();
      }
  
      STDMETHOD_(ULONG, Release)()
      {
          ULONG ref = InternalRelease();
          if (ref == 0)
          {
              delete this;
  
              auto modulePtr = ::Microsoft::WRL::GetModuleBase();
              if (modulePtr != nullptr)
              {
                  modulePtr->DecrementObjectCount();
              }
          }
  
          return ref;
      }
  
      // IInspectable methods
      STDMETHOD(GetIids)(
          _Out_ ULONG *iidCount,
          _When_(*iidCount == 0, _At_(*iids, _Post_null_))
          _When_(*iidCount > 0, _At_(*iids, _Post_notnull_))
          _Result_nullonfailure_ IID **iids)
      {
          return Super::GetImplementedIIDS(this, iidCount, iids);
      }
  
  #if !defined(__WRL_STRICT__) || !defined(__WRL_FORCE_INSPECTABLE_CLASS_MACRO__)
      STDMETHOD(GetRuntimeClassName)(_Out_ HSTRING* runtimeClassName)
      {
          *runtimeClassName = nullptr;
  
          __WRL_ASSERT__(false && "Use InspectableClass macro to set runtime class name and trust level.");
  
  #if (NTDDI_VERSION >= NTDDI_WINBLUE)
          ErrorHelper<RuntimeClassFlagsT::value & InhibitRoOriginateError>::OriginateError(E_NOTIMPL, nullptr);
  #endif // (NTDDI_VERSION >= NTDDI_WINBLUE)
          return E_NOTIMPL;
      }
  
      STDMETHOD(GetTrustLevel)(_Out_ TrustLevel*)
      {
          __WRL_ASSERT__(false && "Use InspectableClass macro to set runtime class name and trust level.");
  #if (NTDDI_VERSION >= NTDDI_WINBLUE)
          ErrorHelper<RuntimeClassFlagsT::value & InhibitRoOriginateError>::OriginateError(E_NOTIMPL, nullptr);
  #endif // (NTDDI_VERSION >= NTDDI_WINBLUE)
          return E_NOTIMPL;
      }
  #endif // !defined(__WRL_STRICT__) || !defined(__WRL_FORCE_INSPECTABLE_CLASS_MACRO__)
  
      STDMETHOD(GetWeakReference)(_Outptr_ IWeakReference **weakReference);
  
      virtual ~RuntimeClassImpl() throw();
  
  protected:
      template <unsigned int RuntimeClassTypeT> friend class Details::RuntimeClassBaseT;
      using ImplementsHelper = typename Details::AdjustImplements<RuntimeClassFlagsT, false, typename IInspectableInjector<I0>::InspectableIfNeeded, I0, IWeakReferenceSource, TInterfaces...>::Type;
      using Super = RuntimeClassBaseT<RuntimeClassFlagsT::value>;
  
      unsigned long InternalAddRef() throw();
  
      unsigned long InternalRelease() throw();
  
      unsigned long GetRefCount() const throw();
  
      friend class WeakReferenceImpl;
  
  #ifdef __WRL_UNITTEST__
  protected:
  #else
  private:
  #endif
      ReferenceCountOrWeakReferencePointer refCount_;
  };
  
  inline INT_PTR EncodeWeakReferencePointer(Microsoft::WRL::Details::WeakReferenceImpl* value)
  {
      return ((reinterpret_cast<INT_PTR>(value) >> 1) | EncodeWeakReferencePointerFlag);
  }
  
  inline Microsoft::WRL::Details::WeakReferenceImpl* DecodeWeakReferencePointer(INT_PTR value)
  {
      return reinterpret_cast<Microsoft::WRL::Details::WeakReferenceImpl*>(value << 1);
  }
  
  #pragma warning(pop) // C6388
  
  template <class RuntimeClassFlagsT, typename I0, typename ...TInterfaces>
  class __declspec(novtable) RuntimeClassImpl<RuntimeClassFlagsT, false, true, true, I0, TInterfaces...> :
      public RuntimeClassImpl<RuntimeClassFlagsT, false, true, false, I0, TInterfaces...>
  {
  };
  
  template <class RuntimeClassFlagsT, typename I0, typename ...TInterfaces>
  class __declspec(novtable) RuntimeClassImpl<RuntimeClassFlagsT, true, true, true, I0, TInterfaces...> :
      public RuntimeClassImpl<RuntimeClassFlagsT, true, true, false, I0, FtmBase, TInterfaces...>
  {
  };
  
  // To minimize breaks with code written against WRL before variadic support was added, this form is maintained.
  template <typename ...TInterfaces>
  struct InterfaceListHelper
  {
      typedef InterfaceListHelper<TInterfaces...> TypeT;
  };
  
  template <
      typename ILst,
      class RuntimeClassFlagsT,
      bool implementsWeakReferenceSource = (RuntimeClassFlagsT::value & InhibitWeakReference) == 0,
      bool implementsInspectable = (RuntimeClassFlagsT::value & WinRt) == WinRt,
      bool implementsFtmBase = __WRL_IMPLEMENTS_FTM_BASE__(RuntimeClassFlagsT::value)
  >
  class RuntimeClass;
  
      
  template <
      typename RuntimeClassFlagsT, 
      bool implementsWeakReferenceSource,
      bool implementsInspectable,
      bool implementsFtmBase,
      typename ...TInterfaces
  >
  class RuntimeClass<InterfaceListHelper<TInterfaces...>, RuntimeClassFlagsT, implementsWeakReferenceSource, implementsInspectable, implementsFtmBase> :
      public RuntimeClassImpl<RuntimeClassFlagsT, implementsWeakReferenceSource, implementsInspectable, implementsFtmBase, TInterfaces...>
  {
  protected:
      HRESULT CustomQueryInterface(REFIID /*riid*/, _Outptr_result_nullonfailure_ void** /*ppvObject*/, _Out_ bool *handled)
      {
          *handled = false;
          return S_OK;
      }
  };
  
  } // namespace Details
  
  // The RuntimeClass IUnknown methods
  // It inherits from Details::RuntimeClass that provides helper methods for reference counting and
  // collecting IIDs
  template <typename ...TInterfaces>
  class RuntimeClass : 
      public Details::RuntimeClassImpl<DETAILS_RTCLASS_FLAGS_ARGUMENTS(RuntimeClassFlags<WinRt>), TInterfaces...>
  {
      RuntimeClass(const RuntimeClass&);
      RuntimeClass& operator=(const RuntimeClass&);
  protected:
      HRESULT CustomQueryInterface(REFIID /*riid*/, _Outptr_result_nullonfailure_ void** /*ppvObject*/, _Out_ bool *handled)
      {
          *handled = false;
          return S_OK;
      }
  public:
      RuntimeClass() throw()
      {
          auto modulePtr = ::Microsoft::WRL::GetModuleBase();
          if (modulePtr != nullptr)
          {
              modulePtr->IncrementObjectCount();
          }
      }
      typedef RuntimeClass RuntimeClassT;
  };
  
  template <unsigned int classFlags, typename ...TInterfaces>
  class RuntimeClass<RuntimeClassFlags<classFlags>, TInterfaces...> :
      public Details::RuntimeClassImpl<DETAILS_RTCLASS_FLAGS_ARGUMENTS(RuntimeClassFlags<classFlags>), TInterfaces...>
  {
      RuntimeClass(const RuntimeClass&);    
      RuntimeClass& operator=(const RuntimeClass&);    
  protected:
      HRESULT CustomQueryInterface(REFIID /*riid*/, _Outptr_result_nullonfailure_ void** /*ppvObject*/, _Out_ bool *handled)
      {
          *handled = false;
          return S_OK;
      }
  public:
      RuntimeClass() throw()
      {
          auto modulePtr = ::Microsoft::WRL::GetModuleBase();
          if (modulePtr != nullptr)
          {
              modulePtr->IncrementObjectCount();
          }
      }
      typedef RuntimeClass RuntimeClassT;
  };
  
  namespace Details
  {
  //Weak reference implementation
      class WeakReferenceImpl final:
          public ::Microsoft::WRL::RuntimeClass<RuntimeClassFlags<ClassicCom>, IWeakReference>,
          public StrongReference
      {
      public:
      WeakReferenceImpl(_In_ IUnknown* unk) throw() : StrongReference(LONG_MAX / 2), unknown_(unk)
      {
          // Set ref count to 2 to avoid unnecessary interlocked increment operation while returning
          // WeakReferenceImpl from GetWeakReference method. One reference is hold by the object the second is hold
          // by the caller of GetWeakReference method.
          refcount_ = 2;
      }
  
      virtual ~WeakReferenceImpl() throw()
      {
      }
  
      STDMETHOD(Resolve)(REFIID riid, _Outptr_result_maybenull_ _Result_nullonfailure_ IInspectable **ppvObject)    
      {            
          *ppvObject = nullptr;
  
          for(;;)
          {
              long ref = this->strongRefCount_;
              if (ref == 0)
              {
                  return S_OK;
              }
  
              // InterlockedCompareExchange calls _InterlockedCompareExchange intrinsic thus we call directly _InterlockedCompareExchange to save the call
              if (::_InterlockedCompareExchange(&this->strongRefCount_, ref + 1, ref) == ref)
              {
  #ifdef _PERF_COUNTERS
                  // This artificially manipulates the strong ref count via AddRef to account for the resolve 
                  // interlocked operation above when tallying reference counting operations.
                  unknown_->AddRef();
                  ::_InterlockedDecrement(&this->strongRefCount_);
  #endif
                  break;
              }
          }
              
          HRESULT hr = unknown_->QueryInterface(riid, reinterpret_cast<void**>(ppvObject));
          unknown_->Release();
          return hr;
      }
  
  
  private:
      IUnknown *unknown_;
  };
  
  template <class RuntimeClassFlagsT, typename I0, typename ...TInterfaces>
  RuntimeClassImpl<RuntimeClassFlagsT, true, true, false, I0, TInterfaces...>::~RuntimeClassImpl() throw()
  {
      if (IsValueAPointerToWeakReference(refCount_.rawValue))
      {
          WeakReferenceImpl* weakRef = DecodeWeakReferencePointer(refCount_.rawValue);
          weakRef->Release();
          weakRef = nullptr;
      }
  }
  
  template <class RuntimeClassFlagsT, typename I0, typename ...TInterfaces>
  unsigned long RuntimeClassImpl<RuntimeClassFlagsT, true, true, false, I0, TInterfaces...>::GetRefCount() const throw()
  {
      ReferenceCountOrWeakReferencePointer currentValue = ReadValueFromPointerNoFence<ReferenceCountOrWeakReferencePointer>(&refCount_);
  
      if (IsValueAPointerToWeakReference(currentValue.rawValue))
      {
          WeakReferenceImpl* weakRef = DecodeWeakReferencePointer(currentValue.rawValue);
          return weakRef->GetStrongReferenceCount();
      }
      else
      {
          return static_cast<unsigned long>(currentValue.refCount);
      }
  }
  
  template <class RuntimeClassFlagsT, typename I0, typename ...TInterfaces>
  unsigned long RuntimeClassImpl<RuntimeClassFlagsT, true, true, false, I0, TInterfaces...>::InternalAddRef() throw()
  {
  #ifdef _PERF_COUNTERS
      IncrementAddRefCount();
  #endif
  
      ReferenceCountOrWeakReferencePointer currentValue = ReadValueFromPointerNoFence<ReferenceCountOrWeakReferencePointer>(&refCount_);
  
      for (;;)
      {
          if (!IsValueAPointerToWeakReference(currentValue.rawValue))
          {
              UINT_PTR updateValue = currentValue.refCount + 1;
  
  #ifdef __WRL_UNITTEST__
              OnBeforeInternalAddRefIncrement();
  #endif
  
              INT_PTR previousValue = reinterpret_cast<INT_PTR>(UnknownInterlockedCompareExchangePointerForIncrement(reinterpret_cast<PVOID*>(&(refCount_.refCount)), reinterpret_cast<PVOID>(updateValue), reinterpret_cast<PVOID>(currentValue.refCount)));
              if (previousValue == currentValue.rawValue)
              {
                  return static_cast<unsigned long>(updateValue);
              }
  
              currentValue.rawValue = previousValue;
          }
          else
          {
              WeakReferenceImpl* weakRef = DecodeWeakReferencePointer(currentValue.rawValue);
              return weakRef->IncrementStrongReference();
          }
      }
  }
  
  template <class RuntimeClassFlagsT, typename I0, typename ...TInterfaces>
  unsigned long RuntimeClassImpl<RuntimeClassFlagsT, true, true, false, I0, TInterfaces...>::InternalRelease() throw()
  {
  #ifdef _PERF_COUNTERS
      IncrementReleaseCount();
  #endif
  
      ReferenceCountOrWeakReferencePointer currentValue = ReadValueFromPointerNoFence<ReferenceCountOrWeakReferencePointer>(&refCount_);
  
      for (;;)
      {
          if (!IsValueAPointerToWeakReference(currentValue.rawValue))
          {
              UINT_PTR updateValue = currentValue.refCount - 1;
  
  #ifdef __WRL_UNITTEST__
              OnBeforeInternalReleaseDecrement();
  #endif
  
              INT_PTR previousValue = reinterpret_cast<INT_PTR>(UnknownInterlockedCompareExchangePointerForIncrement(reinterpret_cast<PVOID*>(&(refCount_.refCount)), reinterpret_cast<PVOID>(updateValue), reinterpret_cast<PVOID>(currentValue.refCount)));
              if (previousValue == currentValue.rawValue)
              {
                  return static_cast<unsigned long>(updateValue);
              }
  
              currentValue.rawValue = previousValue;
          }
          else
          {
              WeakReferenceImpl* weakRef = DecodeWeakReferencePointer(currentValue.rawValue);
              return weakRef->DecrementStrongReference();
          }
      }
  }
  
  template <class RuntimeClassFlagsT, typename I0, typename ...TInterfaces>
  HRESULT RuntimeClassImpl<RuntimeClassFlagsT, true, true, false, I0, TInterfaces...>::GetWeakReference(_Outptr_ IWeakReference **weakReference)
  {
      WeakReferenceImpl* weakRef = nullptr;
      INT_PTR encodedWeakRef = 0;
      ReferenceCountOrWeakReferencePointer currentValue = ReadValueFromPointerNoFence<ReferenceCountOrWeakReferencePointer>(&refCount_);
  
      *weakReference = nullptr;
  
      if (IsValueAPointerToWeakReference(currentValue.rawValue))
      {
          weakRef = DecodeWeakReferencePointer(currentValue.rawValue);
  
          weakRef->AddRef();
          *weakReference = weakRef;
          return S_OK;
      }
  
      // WeakReferenceImpl is created with ref count 2 to avoid interlocked increment
      weakRef = CreateWeakReference(ImplementsHelper::CastToUnknown());
      if (weakRef == nullptr)
      {
          return E_OUTOFMEMORY;
      }
      
      encodedWeakRef = EncodeWeakReferencePointer(weakRef);
  
      for (;;)
      {
          INT_PTR previousValue = 0;
  
          weakRef->SetStrongReference(static_cast<unsigned long>(currentValue.refCount));
  
  #ifdef __WRL_UNITTEST__
          OnBeforeGetWeakReferenceSwap();
  #endif
  
          previousValue = reinterpret_cast<INT_PTR>(UnknownInterlockedCompareExchangePointer(reinterpret_cast<PVOID*>(&(this->refCount_.ifHighBitIsSetThenShiftLeftToYieldPointerToWeakReference)), reinterpret_cast<PVOID>(encodedWeakRef), currentValue.ifHighBitIsSetThenShiftLeftToYieldPointerToWeakReference));
          if (previousValue == currentValue.rawValue)
          {
              // No need to call AddRef in this case, WeakReferenceImpl is created with ref count 2 to avoid interlocked increment
              *weakReference = weakRef;
              return S_OK;
          }
          else if (IsValueAPointerToWeakReference(previousValue))
          {
              // Another thread beat this call to create the weak reference. 
  
              delete weakRef;
  
              weakRef = DecodeWeakReferencePointer(previousValue);
              weakRef->AddRef();
              *weakReference = weakRef;
              return S_OK;
          }
  
          // Another thread won via an AddRef or Release.
          // Let's try again
          currentValue.rawValue = previousValue;
      }
  }
  
  // Memory allocation for object that doesn't support weak references
  // It only allocates memory
  template<typename T>
  class MakeAllocator
  {
  public:
      MakeAllocator() throw() : buffer_(nullptr)
      {
      }
  
      ~MakeAllocator() throw()
      {
          if (buffer_ != nullptr)
          {
              delete buffer_;
          }
      }
  
      void* Allocate() throw()
      {
          __WRL_ASSERT__(buffer_ == nullptr);
          // Allocate memory with operator new(size, nothrow) only
          // This will allow developer to override one operator only
          // to enable different memory allocation model
          buffer_ = (char*) (operator new (sizeof(T), std::nothrow));
          return buffer_;
      }
  
      void Detach() throw()
      {
          buffer_ = nullptr;
      }
  private:
      char* buffer_;
  };
  
  } //Details
  
  #pragma region make overloads
  
  namespace Details {
  
  // Make and MakeAndInitialize functions must not be marked as throw() as the constructor is allowed to throw exceptions.
  template <typename T, typename ...TArgs>
  ComPtr<T> Make(TArgs&&... args)
  {
      static_assert(__is_base_of(Details::RuntimeClassBase, T), "Make can only instantiate types that derive from RuntimeClass");
      ComPtr<T> object;
      Details::MakeAllocator<T> allocator;
      void *buffer = allocator.Allocate();
      if (buffer != nullptr)
      {
          auto ptr = new (buffer)T(Details::Forward<TArgs>(args)...);
          object.Attach(ptr);
          allocator.Detach();
      }
      return object;
  }
  
  #pragma warning(push)
  #pragma warning(disable:6387 6388 28196) // PREFast does not understand call to ComPtr<T>::CopyTo() is safe here
  
  template <typename T, typename I, typename ...TArgs>
  HRESULT MakeAndInitialize(_Outptr_result_nullonfailure_ I** result, TArgs&&... args)
  {
      static_assert(__is_base_of(Details::RuntimeClassBase, T), "Make can only instantiate types that derive from RuntimeClass");
      static_assert(__is_base_of(I, T), "The 'T' runtime class doesn't implement 'I' interface");
      *result = nullptr;
      Details::MakeAllocator<T> allocator;
      void *buffer = allocator.Allocate();
      if (buffer == nullptr) { return E_OUTOFMEMORY; }
      auto ptr = new (buffer)T;
      ComPtr<T> object;
      object.Attach(ptr);
      allocator.Detach();
      HRESULT hr = object->RuntimeClassInitialize(Details::Forward<TArgs>(args)...);
      if (FAILED(hr)) { return hr; }
      return object.CopyTo(result);
  }
  
  #pragma warning(pop) // C6387 C6388 C28196
  
  template <typename T, typename I, typename ...TArgs>
  HRESULT MakeAndInitialize(_Inout_ ComPtrRef<ComPtr<I>> ppvObject, TArgs&&... args)
  {    
      return MakeAndInitialize<T>(ppvObject.ReleaseAndGetAddressOf(), Details::Forward<TArgs>(args)...);
  }
  
  } //end of Details
  
  using Details::MakeAndInitialize;
  using Details::Make;
  
  #pragma endregion // make overloads
  
  namespace Details
  {
      inline WeakReferenceImpl* CreateWeakReference(_In_ IUnknown* unk)
      {
          return Make<WeakReferenceImpl>(unk).Detach();
      }
  }
  
  #define InspectableClass(runtimeClassName, trustLevel) \
      public: \
          static _Null_terminated_ const wchar_t* STDMETHODCALLTYPE InternalGetRuntimeClassName() throw() \
          { \
              static_assert((RuntimeClassT::ClassFlags::value & ::Microsoft::WRL::WinRtClassicComMix) == ::Microsoft::WRL::WinRt || \
                  (RuntimeClassT::ClassFlags::value & ::Microsoft::WRL::WinRtClassicComMix) == ::Microsoft::WRL::WinRtClassicComMix, \
                      "'InspectableClass' macro must not be used with ClassicCom clasess."); \
              static_assert(__is_base_of(::Microsoft::WRL::Details::RuntimeClassBase, RuntimeClassT), "'InspectableClass' macro can only be used with ::Windows::WRL::RuntimeClass types"); \
              static_assert(!__is_base_of(IActivationFactory, RuntimeClassT), "Incorrect usage of IActivationFactory interface. Make sure that your RuntimeClass doesn't implement IActivationFactory interface use ::Windows::WRL::ActivationFactory instead or 'InspectableClass' macro is not used on ::Windows::WRL::ActivationFactory"); \
              return runtimeClassName; \
          } \
          static TrustLevel STDMETHODCALLTYPE InternalGetTrustLevel() throw() \
          { \
              return trustLevel; \
          } \
          STDMETHOD(GetRuntimeClassName)(_Out_ HSTRING* runtimeName) \
          { \
              *runtimeName = nullptr; \
              HRESULT hr = S_OK; \
              auto name = InternalGetRuntimeClassName(); \
              if (name != nullptr) \
              { \
                  hr = ::WindowsCreateString(name, static_cast<UINT32>(::wcslen(name)), runtimeName); \
              } \
              return hr; \
          } \
          STDMETHOD(GetTrustLevel)(_Out_ TrustLevel* trustLvl) \
          { \
              *trustLvl = trustLevel; \
              return S_OK; \
          } \
          STDMETHOD(GetIids)(_Out_ ULONG *iidCount, \
              _When_(*iidCount == 0, _At_(*iids, _Post_null_)) \
              _When_(*iidCount > 0, _At_(*iids, _Post_notnull_)) \
              _Result_nullonfailure_ IID **iids) \
          { \
              return RuntimeClassT::GetIids(iidCount, iids); \
          } \
          STDMETHOD(QueryInterface)(REFIID riid, _Outptr_result_nullonfailure_ void **ppvObject) \
          { \
              bool handled = false; \
              HRESULT hr = CustomQueryInterface(riid, ppvObject, &handled); \
              if (FAILED(hr) || handled) return hr; \
              return RuntimeClassT::QueryInterface(riid, ppvObject); \
          } \
          STDMETHOD_(ULONG, Release)() \
          { \
              return RuntimeClassT::Release(); \
          } \
          STDMETHOD_(ULONG, AddRef)() \
          { \
              return RuntimeClassT::AddRef(); \
          } \
      private:
  
  #define MixInHelper() \
      public: \
          STDMETHOD(QueryInterface)(REFIID riid, _Outptr_result_nullonfailure_ void **ppvObject) \
          { \
              static_assert((RuntimeClassT::ClassFlags::value & ::Microsoft::WRL::WinRt) == 0, "'MixInClass' macro must not be used with WinRt clasess."); \
              static_assert(__is_base_of(::Microsoft::WRL::Details::RuntimeClassBase, RuntimeClassT), "'MixInHelper' macro can only be used with ::Windows::WRL::RuntimeClass types"); \
              static_assert(!__is_base_of(IClassFactory, RuntimeClassT), "Incorrect usage of IClassFactory interface. Make sure that your RuntimeClass doesn't implement IClassFactory interface use ::Windows::WRL::ClassFactory instead or 'MixInHelper' macro is not used on ::Windows::WRL::ClassFactory"); \
              return RuntimeClassT::QueryInterface(riid, ppvObject); \
          } \
          STDMETHOD_(ULONG, Release)() \
          { \
              return RuntimeClassT::Release(); \
          } \
          STDMETHOD_(ULONG, AddRef)() \
          { \
              return RuntimeClassT::AddRef(); \
          } \
      private:
  
  // Please make sure that those macros are in sync with those ones from 'wrl/module.h'
  #ifndef WrlCreatorMapIncludePragmaEx
  #define WrlCreatorMapIncludePragmaEx(className, group)  static_assert(false, "It's required to include 'wrl/module.h' to be able to use 'WrlCreatorMapIncludePragmaEx' macro");
  #endif
  
  #ifndef WrlCreatorMapIncludePragma
  #define WrlCreatorMapIncludePragma(className)  static_assert(false, "It's required to include 'wrl/module.h' to be able to use 'WrlCreatorMapIncludePragma' macro");
  #endif    
  
  #ifndef ActivatableClassWithFactoryEx
  #define ActivatableClassWithFactoryEx(className, factory, groupId)  static_assert(false, "It's required to include 'wrl/module.h' to be able to use 'ActivatableClassWithFactoryEx' macro");
  #endif
  
  #ifndef ActivatableClassWithFactory
  #define ActivatableClassWithFactory(className, factory)  static_assert(false, "It's required to include 'wrl/module.h' to be able to use 'ActivatableClassWithFactory' macro");
  #endif
  
  #ifndef ActivatableClass
  #define ActivatableClass(className)  static_assert(false, "It's required to include 'wrl/module.h' to be able to use 'ActivatableClass' macro");
  #endif
  
  #ifndef ActivatableStaticOnlyFactoryEx
  #define ActivatableStaticOnlyFactoryEx(factory, serverName)  static_assert(false, "It's required to include 'wrl/module.h' to be able to use 'ActivatableStaticOnlyFactoryEx' macro");
  #endif
  
  #ifndef ActivatableStaticOnlyFactory
  #define ActivatableStaticOnlyFactory(factory)  static_assert(false, "It's required to include 'wrl/module.h' to be able to use 'ActivatableStaticOnlyFactory' macro");
  #endif
  
  #ifndef CoCreatableClassWithFactoryEx
  #define CoCreatableClassWithFactoryEx(className, factory, groupId)  static_assert(false, "It's required to include 'wrl/module.h' to be able to use 'CoCreatableClassWithFactory' macro");
  #endif
  
  #ifndef CoCreatableClassWithFactory
  #define CoCreatableClassWithFactory(className, factory)  static_assert(false, "It's required to include 'wrl/module.h' to be able to use 'CoCreatableClassWithFactory' macro");
  #endif
  
  #ifndef CoCreatableClass
  #define CoCreatableClass(className)  static_assert(false, "It's required to include 'wrl/module.h' to be able to use 'CoCreatableClass' macro");
  #endif
  
  #ifndef CoCreatableClassWrlCreatorMapInclude
  #define CoCreatableClassWrlCreatorMapInclude(className)  static_assert(false, "It's required to include 'wrl/module.h' to be able to use 'CoCreatableClassWrlCreatorMapInclude' macro");
  #endif
  
  #ifndef CoCreatableClassWrlCreatorMapIncludeEx
  #define CoCreatableClassWrlCreatorMapIncludeEx(className, groupId)  static_assert(false, "It's required to include 'wrl/module.h' to be able to use 'CoCreatableClassWrlCreatorMapInclude' macro");
  #endif
  
  #undef UnknownIncrementReference
  #undef UnknownDecrementReference
  #undef UnknownBarrierAfterInterlock 
  #undef UnknownInterlockedCompareExchangePointer
  #undef UnknownInterlockedCompareExchangePointerForIncrement
  #undef UnknownInterlockedCompareExchangePointerForRelease
  
  }}    // namespace Microsoft::WRL
  
  #pragma warning(pop)
  
  // Restore packing
  #include <poppack.h>
  
  #endif // _WRL_IMPLEMENTS_H_
  