|
- //*********************************************************
- //
- // Copyright (c) Microsoft. All rights reserved.
- // This code is licensed under the MIT License.
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
- // ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
- // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
- // PARTICULAR PURPOSE AND NONINFRINGEMENT.
- //
- //*********************************************************
- #ifndef __WIL_WRL_INCLUDED
- #define __WIL_WRL_INCLUDED
-
- #include <wrl.h>
- #include "result.h"
- #include "common.h" // wistd type_traits helpers
-
- namespace wil
- {
-
- #ifdef WIL_ENABLE_EXCEPTIONS
- #pragma region Object construction helpers that throw exceptions
-
- /** Used to construct a RuntimeClass based object that uses 2 phase construction.
- Construct a RuntimeClass based object that uses 2 phase construction (by implementing
- RuntimeClassInitialize() and returning error codes for failures.
- ~~~~
- // SomeClass uses 2 phase initialization by implementing RuntimeClassInitialize()
- auto someClass = MakeAndInitializeOrThrow<SomeClass>(L"input", true);
- ~~~~ */
-
- template <typename T, typename... TArgs>
- Microsoft::WRL::ComPtr<T> MakeAndInitializeOrThrow(TArgs&&... args)
- {
- Microsoft::WRL::ComPtr<T> obj;
- THROW_IF_FAILED(Microsoft::WRL::MakeAndInitialize<T>(&obj, Microsoft::WRL::Details::Forward<TArgs>(args)...));
- return obj;
- }
-
- /** Used to construct an RuntimeClass based object that uses exceptions in its constructor (and does
- not require 2 phase construction).
- ~~~~
- // SomeClass uses exceptions for error handling in its constructor.
- auto someClass = MakeOrThrow<SomeClass>(L"input", true);
- ~~~~ */
-
- template <typename T, typename... TArgs>
- Microsoft::WRL::ComPtr<T> MakeOrThrow(TArgs&&... args)
- {
- // This is how you can detect the presence of RuntimeClassInitialize() and find dangerous use.
- // Unfortunately this produces false positives as all RuntimeClass derived classes have
- // a RuntimeClassInitialize() method from their base class.
- // static_assert(!std::is_member_function_pointer<decltype(&T::RuntimeClassInitialize)>::value,
- // "class has a RuntimeClassInitialize member, use MakeAndInitializeOrThrow instead");
- auto obj = Microsoft::WRL::Make<T>(Microsoft::WRL::Details::Forward<TArgs>(args)...);
- THROW_IF_NULL_ALLOC(obj.Get());
- return obj;
- }
- #pragma endregion
-
- #endif // WIL_ENABLE_EXCEPTIONS
-
- /** By default WRL Callback objects are not agile, use this to make an agile one. Replace use of Callback<> with MakeAgileCallback<>.
- Will return null on failure, translate that into E_OUTOFMEMORY using XXX_IF_NULL_ALLOC()
- from wil\result.h to test the result. */
- template<typename TDelegateInterface, typename ...Args>
- ::Microsoft::WRL::ComPtr<TDelegateInterface> MakeAgileCallbackNoThrow(Args&&... args) WI_NOEXCEPT
- {
- using namespace Microsoft::WRL;
- return Callback<Implements<RuntimeClassFlags<ClassicCom>, TDelegateInterface, FtmBase>>(wistd::forward<Args>(args)...);
- }
-
- #ifdef WIL_ENABLE_EXCEPTIONS
- template<typename TDelegateInterface, typename ...Args>
- ::Microsoft::WRL::ComPtr<TDelegateInterface> MakeAgileCallback(Args&&... args)
- {
- auto result = MakeAgileCallbackNoThrow<TDelegateInterface, Args...>(wistd::forward<Args>(args)...);
- THROW_IF_NULL_ALLOC(result);
- return result;
- }
- #endif // WIL_ENABLE_EXCEPTIONS
- } // namespace wil
-
- #endif // __WIL_WRL_INCLUDED
|