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;
65struct enum_doc;
66} // namespace detail
67
86template <class B>
87concept caster_oracle = requires {
88 { B::template has_native_caster<detail::any_type> } -> std::convertible_to<bool>;
89};
90
100template <class B>
101concept two_phase_rod = requires(typename B::module_type& m, const char* s) {
102 B::template reopen_class<detail::any_type>(m, s);
103};
104
262template <class B>
263concept rod =
265 requires {
266 { B::language } -> std::convertible_to<lang>;
267 typename B::module_type;
268 } &&
269 // Module / session machinery + the handle-free per-entity hooks. Every requirement
270 // here takes concrete arguments and returns void or an explicit type, so only the
271 // signatures are substituted — no hook body is instantiated (the reflection/type
272 // template arguments, e.g. `^^int` / `detail::any_type`, reach only the bodies,
273 // which a requires-expression leaves untouched). The per-handle hooks follow in
274 // their own conjunct below; only the make_class/make_enum factories stay unprobed
275 // (see the concept's @note).
276 requires(typename B::module_type& m, const char* s,
277 std::remove_cvref_t<decltype(B::open_module(
278 std::declval<typename B::module_type&>()))> session) {
279 { B::open_module(m) };
280 { B::add_submodule(m, s) } -> std::same_as<typename B::module_type>;
281 B::set_module_doc(m, s);
282 B::close_module(m, session);
283 { B::special_method_name(^^int) } -> std::convertible_to<const char*>;
284 B::template add_function<std::array<std::meta::info, 1>{^^int},
285 detail::any_type>(m);
286 B::template add_variable<^^int, detail::any_type>(m, session);
287 } &&
288 // The per-class / per-enum hooks, probed against the rod's declared handle types
289 // (@ref class_handle_type / @ref enum_handle_type — the associated types naming what
290 // make_class / make_enum yield). All return void, so given the handle type only the
291 // signatures are checked; the placeholder reflections (`^^int`) / types
292 // (@ref detail::any_type) reach only the bodies, which are not instantiated.
293 requires(typename B::template class_handle_type<detail::any_type>& cls,
294 typename B::template enum_handle_type<detail::any_enum>& en,
295 const char* s) {
296 B::template add_constructors<detail::any_type,
297 std::array<std::meta::info, 0>{}, false,
298 false, false>(cls);
299 B::template add_field<^^int, detail::any_type>(cls);
300 B::template add_property<detail::any_type, ^^int, std::meta::info{}>(cls,
301 s);
302 B::template add_method<std::array<std::meta::info, 1>{^^int},
303 detail::any_type>(cls);
304 B::template add_static_method<std::array<std::meta::info, 1>{^^int},
305 detail::any_type>(cls);
306 B::template add_operator<detail::any_type,
307 std::array<std::meta::info, 1>{^^int}>(cls);
308 B::template add_comparisons<detail::any_type,
309 std::array<std::meta::info, 1>{^^int},
310 std::array<bool, 4>{}>(cls);
311 B::template add_stringifier<detail::any_type, ^^int>(cls);
312 B::template add_enumerator<^^int, detail::any_type>(en);
313 B::template finish_enum<detail::any_enum>(en);
314 };
315
403template <class R>
404concept resolution =
405 requires(std::meta::info e, lang L, policy_kind pol, std::meta::info into) {
406 { R::participates(e, L) } -> std::convertible_to<bool>;
407 { R::is_native_base(e, L, into) } -> std::convertible_to<bool>;
408 { R::member_participates(e, L, pol, into) } -> std::convertible_to<bool>;
409 { R::class_member_participates(e, L, pol, into) } -> std::convertible_to<bool>;
410 { R::namespace_participates(e, L, pol, into) } -> std::convertible_to<bool>;
411 { R::counts_as_registered(e, L) } -> std::convertible_to<bool>;
412 } &&
413 requires {
414 { R::template native_bases<^^detail::any_type, lang{}>() }
415 -> std::ranges::range;
416 requires std::same_as<
417 std::ranges::range_value_t<
418 decltype(R::template native_bases<^^detail::any_type, lang{}>())>,
419 std::meta::info>;
420 };
421
436template <class S>
437concept doc_style = requires(const detail::function_doc& d, const detail::enum_doc& e) {
438 { S::format(d) } -> std::same_as<std::string>;
439 { S::format_enum(e) } -> std::same_as<std::string>;
441
442namespace naming {
443
456 @tparam S the candidate style type. */
457template <class S>
458concept name_style = requires {
459 { S::transform_class(^^int) } -> std::convertible_to<std::string>;
460 { S::transform_enum(^^int) } -> std::convertible_to<std::string>;
461 { S::transform_enumerator(^^int) } -> std::convertible_to<std::string>;
462 { S::transform_method(^^int) } -> std::convertible_to<std::string>;
463 { S::transform_static_method(^^int) } -> std::convertible_to<std::string>;
464 { S::transform_function(^^int) } -> std::convertible_to<std::string>;
465 { S::transform_field(^^int) } -> std::convertible_to<std::string>;
466 { S::transform_variable(^^int) } -> std::convertible_to<std::string>;
467 { S::transform_submodule(^^int) } -> std::convertible_to<std::string>;
468};
469
470} // namespace naming
471
472} // namespace welder
The one bindability fact a backend must provide: can it natively convert a type without welder regist...
Definition concepts.hpp:87
A style folds a welder::detail::function_doc into one docstring, and a welder::detail::enum_doc (an e...
Definition concepts.hpp:435
A name style names every kind of entity welder can bind, through one hook per kind.
Definition concepts.hpp:456
The contract a resolution — the carriage's which-participates policy — must satisfy to be injected as...
Definition concepts.hpp:402
The contract a rod (a welder backend, welder::rods::…::rod) must satisfy to plug into the generic dri...
Definition concepts.hpp:263
Does rod B opt into the driver's two-phase namespace sweep — register every welded type's NAME,...
Definition concepts.hpp:101
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 an enum, handed to a style to assemble.
Definition doc.hpp:277
The raw documentation pieces of a function, handed to a style to assemble.
Definition doc.hpp:253