mimic++ v9.2.1
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"
14
15#ifndef MIMICPP_DETAIL_IS_MODULE
16 #include <concepts>
17 #include <tuple>
18 #include <utility>
19#endif
20
21namespace 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
Definition Call.hpp:24