welder 0.1.0
Bindings for annotated C++ types, from C++26 reflection
Loading...
Searching...
No Matches
concepts.hpp
Go to the documentation of this file.
1#pragma once
2#include <array> // overload-group probes (std::array<std::meta::info, N> NTTPs)
3#include <concepts>
4#include <meta>
5#include <ranges>
6#include <string>
7#include <type_traits>
8#include <utility>
9
38
39namespace welder::inline v0 {
40
41namespace detail {
42
51struct any_type {};
52
56enum class any_enum {};
57
58} // namespace detail
59
63namespace detail {
64struct function_doc;
65} // namespace detail
66
85template <class B>
86concept caster_oracle = requires {
87 { B::template has_native_caster<detail::any_type> } -> std::convertible_to<bool>;
88};
89
205template <class B>
206concept rod =
208 requires {
209 { B::language } -> std::convertible_to<lang>;
210 typename B::module_type;
211 } &&
212 // Module / session machinery + the handle-free per-entity hooks. Every requirement
213 // here takes concrete arguments and returns void or an explicit type, so only the
214 // signatures are substituted — no hook body is instantiated (the reflection/type
215 // template arguments, e.g. `^^int` / `detail::any_type`, reach only the bodies,
216 // which a requires-expression leaves untouched). The per-handle hooks follow in
217 // their own conjunct below; only the make_class/make_enum factories stay unprobed
218 // (see the concept's @note).
219 requires(typename B::module_type& m, const char* s,
220 std::remove_cvref_t<decltype(B::open_module(
221 std::declval<typename B::module_type&>()))> session) {
222 { B::open_module(m) };
223 { B::add_submodule(m, s) } -> std::same_as<typename B::module_type>;
224 B::set_module_doc(m, s);
225 B::close_module(m, session);
226 { B::special_method_name(^^int) } -> std::convertible_to<const char*>;
227 B::template add_function<std::array<std::meta::info, 1>{^^int},
228 detail::any_type>(m);
229 B::template add_variable<^^int, detail::any_type>(m, session);
230 } &&
231 // The per-class / per-enum hooks, probed against the rod's declared handle types
232 // (@ref class_handle_type / @ref enum_handle_type — the associated types naming what
233 // make_class / make_enum yield). All return void, so given the handle type only the
234 // signatures are checked; the placeholder reflections (`^^int`) / types
235 // (@ref detail::any_type) reach only the bodies, which are not instantiated.
236 requires(typename B::template class_handle_type<detail::any_type>& cls,
237 typename B::template enum_handle_type<detail::any_enum>& en) {
238 B::template add_constructors<detail::any_type,
239 std::array<std::meta::info, 0>{}, false,
240 false>(cls);
241 B::template add_field<^^int, detail::any_type>(cls);
242 B::template add_method<std::array<std::meta::info, 1>{^^int},
243 detail::any_type>(cls);
244 B::template add_static_method<std::array<std::meta::info, 1>{^^int},
245 detail::any_type>(cls);
246 B::template add_operator<std::array<std::meta::info, 1>{^^int}>(cls);
247 B::template add_enumerator<^^int, detail::any_type>(en);
248 B::template finish_enum<detail::any_enum>(en);
249 };
250
338template <class R>
339concept resolution =
340 requires(std::meta::info e, lang L, policy_kind pol, std::meta::info into) {
341 { R::participates(e, L) } -> std::convertible_to<bool>;
342 { R::is_native_base(e, L, into) } -> std::convertible_to<bool>;
343 { R::member_participates(e, L, pol, into) } -> std::convertible_to<bool>;
344 { R::class_member_participates(e, L, pol, into) } -> std::convertible_to<bool>;
345 { R::namespace_participates(e, L, pol, into) } -> std::convertible_to<bool>;
346 { R::counts_as_registered(e, L) } -> std::convertible_to<bool>;
347 } &&
348 requires {
349 { R::template native_bases<^^detail::any_type, lang{}>() }
350 -> std::ranges::range;
351 requires std::same_as<
352 std::ranges::range_value_t<
353 decltype(R::template native_bases<^^detail::any_type, lang{}>())>,
354 std::meta::info>;
355 };
356
367template <class S>
368concept doc_style = requires(const detail::function_doc& d) {
369 { S::format(d) } -> std::same_as<std::string>;
371
372namespace naming {
373
386 @tparam S the candidate style type. */
387template <class S>
388concept name_style = requires {
389 { S::transform_class(^^int) } -> std::convertible_to<std::string>;
390 { S::transform_enum(^^int) } -> std::convertible_to<std::string>;
391 { S::transform_enumerator(^^int) } -> std::convertible_to<std::string>;
392 { S::transform_method(^^int) } -> std::convertible_to<std::string>;
393 { S::transform_static_method(^^int) } -> std::convertible_to<std::string>;
394 { S::transform_function(^^int) } -> std::convertible_to<std::string>;
395 { S::transform_field(^^int) } -> std::convertible_to<std::string>;
396 { S::transform_variable(^^int) } -> std::convertible_to<std::string>;
397 { S::transform_submodule(^^int) } -> std::convertible_to<std::string>;
398};
399
400} // namespace naming
401
402} // namespace welder
The one bindability fact a backend must provide: can it natively convert a type without welder regist...
Definition concepts.hpp:86
A style folds a welder::detail::function_doc into one docstring.
Definition concepts.hpp:366
A name style names every kind of entity welder can bind, through one hook per kind.
Definition concepts.hpp:386
The contract a resolution — the carriage's which-participates policy — must satisfy to be injected as...
Definition concepts.hpp:337
The contract a rod (a welder backend, welder::rods::…::rod) must satisfy to plug into the generic dri...
Definition concepts.hpp:206
The stored forms of the annotation vocabulary.
any_enum
A placeholder enum type for shape-probing the enum hooks against a rod's enum_handle_type<E> — any_ty...
Definition concepts.hpp:56
policy_kind
How greedily a type's members are reflected for binding.
lang
The target languages welder ships rods for — but not the whole value space.
Definition lang.hpp:42
A placeholder class type for shape-probing a member template inside a concept.
Definition concepts.hpp:51
The raw documentation pieces of a function, handed to a style to assemble.
Definition doc.hpp:253