-
Notifications
You must be signed in to change notification settings - Fork 247
/
base_composable.h
80 lines (67 loc) · 2.63 KB
/
base_composable.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
namespace winrt::impl
{
template <typename D>
struct composable_factory
{
template <typename I, typename... Args>
static I CreateInstance(const Windows::Foundation::IInspectable& outer, Windows::Foundation::IInspectable& inner, Args&&... args)
{
static_assert(std::is_base_of_v<Windows::Foundation::IInspectable, I>, "Requested interface must derive from winrt::Windows::Foundation::IInspectable");
inner = CreateInstanceImpl(outer, std::forward<Args>(args)...);
return inner.as<I>();
}
private:
template <typename... Args>
static Windows::Foundation::IInspectable CreateInstanceImpl(const Windows::Foundation::IInspectable& outer, Args&&... args)
{
// Very specific dance here. The return value must have a ref on the outer, while inner must have a ref count of 1.
// Be sure not to make a delegating QueryInterface call because the controlling outer is not fully constructed yet.
com_ptr<D> instance = make_self<D>(std::forward<Args>(args)...);
instance->m_outer = static_cast<inspectable_abi*>(get_abi(outer));
Windows::Foundation::IInspectable inner;
attach_abi(inner, to_abi<INonDelegatingInspectable>(detach_abi(instance)));
return inner;
}
};
template <typename T, typename D, typename I>
class WINRT_IMPL_EMPTY_BASES produce_dispatch_to_overridable_base
{
protected:
D& shim() noexcept
{
return static_cast<T&>(*this).instance;
}
I shim_overridable()
{
void* result{};
if (shim().outer())
{
check_hresult(shim().QueryInterface(guid_of<I>(), &result));
}
return { result, take_ownership_from_abi };
}
};
template <typename T, typename D, typename I>
struct produce_dispatch_to_overridable;
template <typename D, typename... I>
class dispatch_to_overridable
{
class wrapper : public produce_dispatch_to_overridable<wrapper, D, I>...
{
D& instance;
template <typename, typename, typename>
friend class produce_dispatch_to_overridable_base;
template <typename, typename...>
friend class dispatch_to_overridable;
explicit wrapper(D& d) : instance(d) {}
public:
wrapper(const wrapper&) = delete;
wrapper(wrapper&&) = default;
};
public:
static wrapper overridable(D& instance) noexcept
{
return wrapper{ instance };
}
};
}