mimic++
v10.0.1
Toggle main menu visibility
Loading...
Searching...
No Matches
CallConvention.hpp
Go to the documentation of this file.
1
// Copyright Dominic (DNKpp) Koepke 2024 - 2025.
2
// Distributed under the Boost Software License, Version 1.0.
3
// (See accompanying file LICENSE_1_0.txt or copy at
4
// https://www.boost.org/LICENSE_1_0.txt)
5
6
#ifndef MIMICPP_CALL_CONVENTION_HPP
7
#define MIMICPP_CALL_CONVENTION_HPP
8
9
#include "
mimic++/Fwd.hpp
"
10
#include "
mimic++/TypeTraits.hpp
"
11
#include "
mimic++/config/Config.hpp
"
12
#include "
mimic++/reporting/TargetReport.hpp
"
13
#include "
mimic++/utilities/SourceLocation.hpp
"
14
15
#ifndef MIMICPP_DETAIL_IS_MODULE
16
#include <concepts>
17
#include <tuple>
18
#include <utility>
19
#endif
20
21
namespace
mimicpp
22
{
50
57
}
58
66
#define MIMICPP_DETAIL_DEFINE_REMOVE_CALL_CONVENTION(call_convention, specs) \
67
template <typename Return, typename... Params> \
68
struct remove_call_convention<Return call_convention(Params...) specs> \
69
{ \
70
using type = Return(Params...) specs; \
71
}
72
80
#define MIMICPP_DETAIL_DEFINE_ADD_CALL_CONVENTION(call_convention, specs) \
81
template <typename Return, typename... Params> \
82
struct add_call_convention<Return(Params...) specs> \
83
{ \
84
using type = Return call_convention(Params...) specs; \
85
}
86
93
#define MIMICPP_DETAIL_DEFINE_CALL_CONVENTION_CALL_INTERFACE(call_convention, specs) \
94
template <typename Derived, typename Return, typename... Params> \
95
class CallInterface< \
96
Derived, \
97
Return call_convention(Params...) specs> \
98
{ \
99
public: \
100
constexpr Return call_convention operator()( \
101
Params... params, \
102
::mimicpp::util::SourceLocation from = {}) specs \
103
{ \
104
return static_cast<Derived const&>(*this) \
105
.handle_call( \
106
::mimicpp::reporting::TypeReport::make<Return(Params...) specs>(), \
107
::std::tuple{::std::ref(params)...}, \
108
::std::move(from)); \
109
} \
110
}
111
118
#define MIMICPP_DETAIL_DEFINE_CALL_CONVENTION_SPECIALIZATIONS(call_convention, specs) \
119
MIMICPP_DETAIL_DEFINE_REMOVE_CALL_CONVENTION(call_convention, specs); \
120
MIMICPP_DETAIL_DEFINE_ADD_CALL_CONVENTION(call_convention, specs); \
121
MIMICPP_DETAIL_DEFINE_CALL_CONVENTION_CALL_INTERFACE(call_convention, specs)
122
131
#define MIMICPP_REGISTER_CALL_CONVENTION(call_convention, namespace_name) \
132
namespace namespace_name \
133
{ \
134
struct tag \
135
{ \
136
}; \
137
\
138
constexpr bool is_default_call_convention = ::std::same_as<void(), void call_convention()>; \
139
\
140
template <typename Signature> \
141
struct remove_call_convention; \
142
\
143
template <typename Signature> \
144
using remove_call_convention_t = typename remove_call_convention<Signature>::type; \
145
\
146
template <typename Signature> \
147
concept has_call_convention = !::std::same_as<Signature, remove_call_convention_t<Signature>>; \
148
\
149
template <typename Signature> \
150
struct add_call_convention; \
151
\
152
template <typename Signature> \
153
using add_call_convention_t = typename add_call_convention<Signature>::type; \
154
\
155
template <has_call_convention Signature> \
156
struct add_call_convention<Signature> \
157
{ \
158
using type = Signature; \
159
}; \
160
\
161
template <typename Derived, typename Signature> \
162
class CallInterface; \
163
\
164
MIMICPP_DETAIL_DEFINE_CALL_CONVENTION_SPECIALIZATIONS(call_convention, ); \
165
MIMICPP_DETAIL_DEFINE_CALL_CONVENTION_SPECIALIZATIONS(call_convention, noexcept); \
166
MIMICPP_DETAIL_DEFINE_CALL_CONVENTION_SPECIALIZATIONS(call_convention, const); \
167
MIMICPP_DETAIL_DEFINE_CALL_CONVENTION_SPECIALIZATIONS(call_convention, const noexcept); \
168
MIMICPP_DETAIL_DEFINE_CALL_CONVENTION_SPECIALIZATIONS(call_convention, &); \
169
MIMICPP_DETAIL_DEFINE_CALL_CONVENTION_SPECIALIZATIONS(call_convention, & noexcept); \
170
MIMICPP_DETAIL_DEFINE_CALL_CONVENTION_SPECIALIZATIONS(call_convention, const&); \
171
MIMICPP_DETAIL_DEFINE_CALL_CONVENTION_SPECIALIZATIONS(call_convention, const& noexcept); \
172
MIMICPP_DETAIL_DEFINE_CALL_CONVENTION_SPECIALIZATIONS(call_convention, &&); \
173
MIMICPP_DETAIL_DEFINE_CALL_CONVENTION_SPECIALIZATIONS(call_convention, && noexcept); \
174
MIMICPP_DETAIL_DEFINE_CALL_CONVENTION_SPECIALIZATIONS(call_convention, const&&); \
175
MIMICPP_DETAIL_DEFINE_CALL_CONVENTION_SPECIALIZATIONS(call_convention, const&& noexcept); \
176
} \
177
/* Wrapping the specializations in the actual namespace is required for gcc 11*/
\
178
namespace mimicpp \
179
{ \
180
template <::namespace_name::has_call_convention Signature> \
181
requires(!::namespace_name::is_default_call_convention) \
182
struct signature_call_convention<Signature> \
183
{ \
184
using type = ::namespace_name::tag; \
185
}; \
186
\
187
/* In cases, where the call-convention is the default, we still want to get this tag, \
188
because it's not guaranteed, that it will be applied on member functions (e.g. __vectorcall). \
189
Due to this, we must explicitly mark the call-interface operators.*/
\
190
template <::mimicpp::has_default_call_convention Signature> \
191
requires ::namespace_name::is_default_call_convention \
192
struct signature_call_convention<Signature> \
193
{ \
194
using type = ::namespace_name::tag; \
195
}; \
196
\
197
template <> \
198
struct call_convention_traits<::namespace_name::tag> \
199
{ \
200
using tag_t = ::namespace_name::tag; \
201
\
202
template <typename Signature> \
203
using remove_call_convention_t = ::namespace_name::remove_call_convention_t<Signature>; \
204
\
205
template <typename Signature> \
206
using add_call_convention_t = ::namespace_name::add_call_convention_t<Signature>; \
207
\
208
template <typename Derived, typename Signature> \
209
using call_interface_t = ::namespace_name::CallInterface<Derived, Signature>; \
210
}; \
211
}
212
213
#endif
Config.hpp
Fwd.hpp
SourceLocation.hpp
TargetReport.hpp
TypeTraits.hpp
mimicpp
Definition
Call.hpp:24
mimic++
CallConvention.hpp
Generated on
for mimic++ by
1.18.0