welder 0.1.0
Bindings for annotated C++ types, from C++26 reflection
Loading...
Searching...
No Matches
bindable.hpp File Reference

Backend-agnostic bindability ("can the target language represent this type?"). More...

#include <array>
#include <concepts>
#include <cstddef>
#include <meta>
#include <type_traits>
#include <utility>
#include <deque>
#include <list>
#include <map>
#include <memory>
#include <expected>
#include <optional>
#include <set>
#include <span>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <variant>
#include <vector>
#include <welder/bind_traits.hpp>
#include <welder/concepts.hpp>
#include <welder/reflect.hpp>
Include dependency graph for bindable.hpp:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  welder::welded_registration
 The default registration oracle of the bindability gate: a program-defined class/enum type counts as registered iff it is welded for the language. More...
struct  welder::detail::wrapper_spec
 One row of the element-wise STL-wrapper table. More...

Namespaces

namespace  welder
namespace  welder::detail
 The stored forms of the annotation vocabulary.

Functions

template<caster_oracle B, class T, lang L, class Reg>
consteval bool welder::detail::bindable ()
 Forward declaration: bindable() recurses through a container's element types.
consteval std::array< wrapper_spec, 18 > welder::detail::stl_wrappers ()
 The element-wise STL-wrapper table welder recurses into.
consteval long welder::detail::wrapper_value_count (std::meta::info type)
 How many leading arguments of type to recurse if it is a listed wrapper.
template<std::meta::info Type, std::size_t N>
consteval std::array< std::meta::info, N > welder::detail::leading_args ()
 The first N template arguments of Type, as a splice-ready static array.
consteval bool welder::detail::is_expected_specialization (std::meta::info type)
 Is type a std::expected specialization — the fallible-result family?
consteval std::meta::info welder::detail::expected_value_arg (std::meta::info type)
 The VALUE argument of the std::expected type (its first).
consteval bool welder::detail::is_span_specialization (std::meta::info type)
 Is type a std::span specialization — the non-owning sequence view?
consteval std::meta::info welder::detail::span_element_arg (std::meta::info type)
 The ELEMENT argument of the std::span type (its first).
template<caster_oracle B, lang L, class Reg, auto Args, std::size_t... I>
consteval bool welder::detail::args_bindable (std::index_sequence< I... >)
 Whether every one of a wrapper's value arguments (spliced back to types) binds.
template<class T>
consteval bool welder::detail::mentions_union ()
 Forward declaration: mentions_union() recurses like bindable() does.
template<auto Args, std::size_t... I>
consteval bool welder::detail::args_mention_union (std::index_sequence< I... >)
 Whether every one of a wrapper's value arguments mentions a union.
template<caster_oracle B, class T, lang L, class Reg = welded_registration>
consteval bool welder::bindable ()
 Is T bindable to language L under backend B?
template<caster_oracle B, class T, lang L, class Reg = welded_registration>
consteval void welder::assert_bindable ()
 Hard error the instant welder would bind an unbindable type.
template<caster_oracle B, std::meta::info Fn, lang L, class Reg, std::size_t... I>
consteval void welder::detail::assert_params_bindable (std::index_sequence< I... >)
 Assert every parameter type of Fn binds.
template<caster_oracle B, std::meta::info Fn, lang L, class Reg = welded_registration>
consteval void welder::assert_signature_bindable ()
 Assert every parameter type and the (non-void) return type of Fn binds.
template<caster_oracle B, std::meta::info Member, lang L, class Reg = welded_registration>
consteval void welder::assert_member_bindable ()
 Assert the type of a data member / namespace variable binds, unless trusted.
template<caster_oracle B, std::meta::info Fn, lang L, class Reg = welded_registration>
consteval void welder::assert_callable_bindable ()
 Assert a function/method/operator/constructor signature binds, unless trusted.
template<caster_oracle B, std::meta::info Fn, lang L, class Reg = welded_registration>
consteval void welder::assert_setter_bindable ()
 Assert a property setter's parameter binds, unless trusted — the write half of the getter/setter machinery.
template<caster_oracle B, std::meta::info Fn, std::meta::info Type, lang L, class Reg, std::size_t... I>
consteval void welder::detail::assert_operands (std::index_sequence< I... >)
 The parameter walk behind assert_operands_bindable — gate each parameter that is not the anchor type itself.
template<caster_oracle B, std::meta::info Fn, std::meta::info Type, lang L, class Reg = welded_registration>
consteval void welder::assert_operands_bindable ()
 Assert the operand types of an operator<=> overload bind, unless the overload is trusted — the comparison-synthesis gate.

Detailed Description

Backend-agnostic bindability ("can the target language represent this type?").

Before welder emits a binding for any surface (a data member, a parameter, a return type, a namespace variable), it checks that the backend can actually turn that C++ type into a meaningful target value. Binding one it cannot is never useful: the attribute would be unusable AND generated stubs would reference an unimportable type. So welder makes it a hard compile error (see assert_bindable()), whose remedy is to weld the type, give it a backend type converter, or mark::exclude the member.

UNIONS are categorically unbindable — welded or not. C++ offers no way to observe which union member is active, so any generated accessor could read an inactive member (undefined behavior); welder refuses rather than emit that surface, and the diagnostic names the real fix: std::variant, which every rod converts natively and which knows its active alternative. The trust hatches still apply (checked before the union branch), covering a union the user hand-registers with the backend.

Only ONE thing is backend-specific here: the leaf test — "does the backend natively convert this scalar/string/user-registered type, or does it need welder to register a class/enum for it?". A backend supplies that via the welder::caster_oracle concept (in <welder/concepts.hpp>); the STL-wrapper recursion below is shared, so a new backend inherits container/optional/variant/smart-pointer handling for free.

Definition in file bindable.hpp.