welder 0.1.0
Bindings for annotated C++ types, from C++26 reflection
Loading...
Searching...
No Matches
rod.hpp
Go to the documentation of this file.
1#pragma once
25
26#include <array>
27#include <cstddef>
28#include <meta>
29#include <ostream>
30#include <string>
31#include <type_traits>
32#include <utility>
33
34#include <welder/welder.hpp>
36#include <welder/rods/python/opaque_containers/marks.hpp> // marked_by_value
37
38namespace welder::inline v0::rods::opaque_containers {
39
43struct rod {
44 static constexpr lang language{lang::py};
45
52 std::string prefix{};
53 };
55
58 struct class_handle {
60 };
61
63 struct enum_handle {};
64
65 template <class> using class_handle_type = class_handle;
66 template <class> using enum_handle_type = enum_handle;
67
68 struct session {};
69
74 template <class T>
75 static constexpr bool has_native_caster = true;
76
79 static consteval const char* special_method_name(std::meta::info) {
80 return nullptr;
81 }
82
83 // --- class binding: pass the document down to the per-member hooks -------
84
85 template <class T, auto Bases, std::size_t... I>
86 static class_handle make_class(module_type& m, const char* /*name*/,
87 const char* /*doc*/, std::index_sequence<I...>) {
88 return {m.doc};
89 }
90
92 template <class T, std::meta::info Decl, auto Bases, std::size_t... I>
93 static class_handle make_class(module_type& m, const char* /*name*/,
94 const char* /*doc*/, std::index_sequence<I...>) {
95 return {m.doc};
96 }
97 template <class T, auto Bases, std::size_t... I>
99 const char* /*name*/, const char* /*doc*/,
100 std::index_sequence<I...>) {
101 return {m.doc};
102 }
103
107 template <class T, auto Ctors, bool HasDefault, bool Aggregate, bool Copyable,
108 class Style = ::welder::naming::none>
109 static void add_constructors(class_handle& cls) {
110 template for (constexpr auto ctor : std::define_static_array(Ctors))
111 cls.doc->template collect_callable<ctor, Style>(false);
112 }
113
117 template <std::meta::info Mem, class Style = ::welder::naming::none>
118 static void add_field(class_handle& cls) {
119 cls.doc->template collect<std::meta::type_of(Mem), Style,
120 std::meta::parent_of(Mem), Mem>(
122 }
123
127 template <class T, std::meta::info Getter, std::meta::info Setter>
128 static void add_property(class_handle& cls, const char*) {
129 cls.doc->template collect_callable<Getter, ::welder::naming::none>(false);
130 if constexpr (Setter != std::meta::info{})
131 cls.doc->template collect_callable<Setter, ::welder::naming::none>(false);
132 }
133
134 template <auto Fns, class Style = ::welder::naming::none>
135 static void add_method(class_handle& cls) {
136 template for (constexpr auto fn : std::define_static_array(Fns))
137 cls.doc->template collect_callable<fn, Style>(true);
138 }
139 template <auto Fns, class Style = ::welder::naming::none>
140 static void add_static_method(class_handle& cls) {
141 template for (constexpr auto fn : std::define_static_array(Fns))
142 cls.doc->template collect_callable<fn, Style>(true);
143 }
144 template <class T, auto Fns>
145 static void add_operator(class_handle& cls) {
146 template for (constexpr auto fn : std::define_static_array(Fns))
147 cls.doc->template collect_callable<fn, ::welder::naming::none>(false);
148 }
149 template <class T, auto Fns, auto Covered>
150 static void add_comparisons(class_handle&) {} // spaceship operands are the anchor type
151 template <class T, std::meta::info Fn>
152 static void add_stringifier(class_handle&) {} // ostream inserter: no container surface
153
154 // --- enum binding: nothing to collect -----------------------------------
155
156 template <class E>
157 static enum_handle make_enum(module_type&, const char*,
158 const ::welder::detail::enum_doc&) {
159 return {};
160 }
161 template <class E>
163 const ::welder::detail::enum_doc&) {
164 return {};
165 }
166 template <std::meta::info, class = ::welder::naming::none>
168 template <class E> static void finish_enum(enum_handle&) {}
169
170 // --- namespace / module binding -----------------------------------------
171
172 static session open_module(module_type&) { return {}; }
173 static void set_module_doc(module_type&, const char*) {}
174
177 template <auto Fns, class Style = ::welder::naming::none>
178 static void add_function(module_type& m, const char* = nullptr) {
179 template for (constexpr auto fn : std::define_static_array(Fns))
180 m.doc->template collect_callable<fn, Style>(true);
181 }
182
185 template <std::meta::info Var, class Style = ::welder::naming::none>
186 static void add_variable(module_type& m, session&, const char* = nullptr) {
187 m.doc->template collect<std::meta::type_of(Var), Style,
188 std::meta::parent_of(Var), Var>(false, true);
189 }
190
192 static module_type add_submodule(module_type& m, const char* name) {
193 return module_type{m.doc, m.prefix.empty() ? std::string{name}
194 : m.prefix + "." + name};
195 }
197
198 // --- whole-header generation (this backend's extra entry point) ----------
199
207 template <std::meta::info Ns, class Style = ::welder::naming::none>
208 static void generate(std::ostream& os) {
209 static_assert(std::meta::is_namespace(Ns),
210 "welder: opaque_containers::generate<Ns>: Ns must reflect a "
211 "namespace");
212 document doc{};
213 module_type m{&doc, {}};
214 ::welder::welder<rod, Style>::template weld_namespace<Ns>(m);
215 // namespace_name is consteval (heap std::string), so materialize its result
216 // to a static C-string before it crosses into this runtime call.
217 os << doc.render(std::define_static_string(namespace_name(Ns)));
218 }
219};
220
221static_assert(::welder::rod<rod>,
222 "welder::rods::opaque_containers::rod must satisfy welder::rod");
223
224} // namespace welder::inline v0::rods::opaque_containers
The contract a rod (a welder backend, welder::rods::…::rod) must satisfy to plug into the generic dri...
Definition concepts.hpp:263
The one opt-out mark of the opaque-container generator (welder::rods::opaque_containers::rod): welder...
consteval std::string namespace_name(std::meta::info ns)
The fully-qualified spelling of namespace ns for a namespace X { … } header block (no leading :: — ge...
Definition document.hpp:234
consteval bool marked_by_value(std::meta::info entity)
Does entity carry a by_value mark?
Definition marks.hpp:37
consteval detail::doc_spec< N > doc(const char(&s)[N])
Attach a docstring to a namespace, class, function, or function parameter.
lang
The target languages welder ships rods for — but not the whole value space.
Definition lang.hpp:42
@ py
Python (via the pybind11 and nanobind backends).
Definition lang.hpp:43
The text-emitting core of welder's opaque-container generator rod: the collector that gathers the ref...
The identity style: bind every C++ identifier unchanged.
Definition naming.hpp:259
The accumulator threaded through the rod's emission hooks: the deduped set of reference containers th...
Definition document.hpp:362
The per-class handle: it carries the document so the per-member hooks (add_field / add_method / …) ca...
Definition rod.hpp:58
The enum handle — enums use no containers, so it carries nothing.
Definition rod.hpp:63
A copyable handle onto the growing document threaded through every emission primitive (the rod's modu...
Definition rod.hpp:50
static void set_module_doc(module_type &, const char *)
Definition rod.hpp:173
static enum_handle make_enum(module_type &, const char *, const ::welder::detail::enum_doc &)
Definition rod.hpp:157
static session open_module(module_type &)
Definition rod.hpp:172
static class_handle make_class(module_type &m, const char *, const char *, std::index_sequence< I... >)
The declaring-entity-aware form the carriage prefers (see bind_type); the generator keys off member t...
Definition rod.hpp:93
static void add_stringifier(class_handle &)
Definition rod.hpp:152
static void add_field(class_handle &cls)
Collect the container(s) in data member Mem's type — excluded when Mem carries [[=welder::rods::pytho...
Definition rod.hpp:118
static void add_static_method(class_handle &cls)
Definition rod.hpp:140
static void generate(std::ostream &os)
Emit the opaque-container header for the welded types in namespace Ns to os.
Definition rod.hpp:208
static void finish_enum(enum_handle &)
Definition rod.hpp:168
static module_type add_submodule(module_type &m, const char *name)
Recurse into a nested namespace, carrying the document through.
Definition rod.hpp:192
static consteval const char * special_method_name(std::meta::info)
No operators expose special names here (containers are collected from operator signatures directly).
Definition rod.hpp:79
static void add_enumerator(enum_handle &)
Definition rod.hpp:167
static void add_method(class_handle &cls)
Definition rod.hpp:135
static constexpr bool has_native_caster
Permissive: the generator only reads the welded surface to find containers, so it does not need a bac...
Definition rod.hpp:75
static class_handle make_class(module_type &m, const char *, const char *, std::index_sequence< I... >)
Definition rod.hpp:86
static constexpr lang language
Opaque containers are Python-only.
Definition rod.hpp:44
static void add_property(class_handle &cls, const char *)
Collect from the property accessor signatures (getter return, setter param).
Definition rod.hpp:128
static class_handle make_nested_class(module_type &m, class_handle &, const char *, const char *, std::index_sequence< I... >)
Definition rod.hpp:98
static void add_operator(class_handle &cls)
Definition rod.hpp:145
static void close_module(module_type &, session &)
Definition rod.hpp:196
static enum_handle make_nested_enum(module_type &, class_handle &, const char *, const ::welder::detail::enum_doc &)
Definition rod.hpp:162
static void add_variable(module_type &m, session &, const char *=nullptr)
Collect the container(s) in a namespace variable's type (a Style-aware site).
Definition rod.hpp:186
static void add_constructors(class_handle &cls)
Collect from each participating constructor's parameter types, styling parameter names through Style ...
Definition rod.hpp:109
static void add_comparisons(class_handle &)
Definition rod.hpp:150
static void add_function(module_type &m, const char *=nullptr)
Collect from a free function's overload group signatures (a Style-aware site).
Definition rod.hpp:178
welder's binding entry point, parameterized on a rod.
Definition welder.hpp:85
welder's binding entry point: the welder::welder struct.