di 0.1.0
Loading...
Searching...
No Matches
erased_call.h
Go to the documentation of this file.
1#pragma once
2
8#include "di/meta/algorithm.h"
9#include "di/meta/language.h"
10#include "di/meta/util.h"
12
13namespace di::any::detail {
14template<typename Method, typename Storage, typename T>
15struct ErasedCallImpl;
16
17template<typename Tag, typename Storage, typename R, concepts::RemoveCVRefSameAs<This> Self, typename... BArgs,
18 typename T>
19struct ErasedCallImpl<Method<Tag, R(Self, BArgs...)>, Storage, T> {
20 constexpr static auto call(void* storage, BArgs... bargs) -> R {
21 using M = Method<Tag, R(Self, BArgs...)>;
22
23 static_assert(concepts::AnyStorable<T, Storage>,
24 "Cannot create a vtable function for T not storable in Storage.");
25 static_assert(concepts::MethodCallableWith<M, meta::Like<Self, T>>,
26 "Cannot create a vtable function because the Method is not callable for T.");
27
28 auto const tag = Tag {};
29
31 auto* typed_storage = static_cast<QualifiedStorage*>(storage);
32 auto* object = typed_storage->template down_cast<meta::RemoveReference<T>>();
33
34 if constexpr (concepts::TagInvocableTo<Tag const&, R, M, meta::Like<Self, T>, BArgs...>) {
35 if constexpr (concepts::LanguageVoid<R>) {
36 (void) tag_invoke(tag, M {}, util::forward_like<Self>(*object), util::forward<BArgs>(bargs)...);
37 } else {
38 return tag_invoke(tag, M {}, util::forward_like<Self>(*object), util::forward<BArgs>(bargs)...);
39 }
40 } else {
41 return function::invoke_r<R>(tag, util::forward_like<Self>(*object), util::forward<BArgs>(bargs)...);
42 }
43 }
44};
45}
meta::Type< StorageT< Send, Alloc > > Storage
Definition start_detached.h:87
constexpr auto invoke_r
Definition invoke.h:103
Conditional< is_const, T const, T > MaybeConst
Definition util.h:9
di::meta::Decay< decltype(T)> Tag
Definition tag_invoke.h:28
constexpr auto forward_like(U &&value) -> decltype(auto)
Definition forward_like.h:8
constexpr tag_invoke_detail::TagInvokeFn tag_invoke
Definition tag_invoke.h:22