46namespace welder::inline v0::naming {
63consteval std::vector<std::string>
split_words(std::string_view
id) {
64 auto is_upper = [](
char c) {
return c >=
'A' && c <=
'Z'; };
65 auto is_lower = [](
char c) {
return c >=
'a' && c <=
'z'; };
66 auto is_digit = [](
char c) {
return c >=
'0' && c <=
'9'; };
67 auto to_lower = [&](
char c) {
return is_upper(c) ? char(c -
'A' +
'a') : c; };
69 std::vector<std::string> words{};
77 for (std::string::size_type i{0}; i <
id.size(); ++i) {
79 if (c ==
'_' || c ==
'-' || c ==
' ') {
84 const char prev{
id[i - 1]};
85 const bool hump{is_upper(c) && (is_lower(prev) || is_digit(prev))};
86 const bool acronym_end{is_upper(c) && is_upper(prev) &&
87 i + 1 <
id.size() && is_lower(
id[i + 1])};
88 if (hump || acronym_end)
91 cur.push_back(to_lower(c));
112consteval std::string
join_words(
const std::vector<std::string>& words,
114 auto upper = [](
char c) {
return (c >=
'a' && c <=
'z') ? char(c -
'a' +
'A') : c; };
115 auto cap = [&](std::string w) {
121 for (std::string::size_type i{0}; i < words.size(); ++i) {
131 for (
char c : words[i])
140 out += i ? cap(words[i]) : words[i];
143 out += cap(words[i]);
158 std::string::size_type lead{0};
159 while (lead <
id.size() &&
id[lead] ==
'_')
161 if (lead ==
id.size())
162 return std::string{
id};
163 std::string::size_type trail{0};
164 while (
id[
id.size() - 1 - trail] ==
'_')
167 std::string(trail,
'_');
190 static consteval std::string
id(std::meta::info e) {
191 return std::string{std::meta::identifier_of(e)};
194static_assert(name_style<none>,
"welder: naming::none is not a name_style");
200template <case_kind Kind>
213 static consteval std::string
in(std::meta::info e) {
214 return restyle(std::meta::identifier_of(e), Kind);
225 "welder: naming::screaming_snake_case is not a name_style");
235namespace welder::inline v0 {
261template <std::meta::info Ent, lang L>
263 template for (
constexpr auto a :
264 std::define_static_array(std::meta::annotations_of(Ent))) {
265 constexpr std::meta::info t{std::meta::type_of(a)};
266 if constexpr (std::meta::has_template_arguments(t) &&
268 using spec_type = [:t:];
269 constexpr auto spec{std::meta::extract<spec_type>(a)};
270 if constexpr (spec.mask == 0 || (spec.mask &
lang_bit(L)) != 0)
271 return std::define_static_string(spec.name.data);
293template <std::meta::info Ent, lang L,
class Style, ent_kind K>
298 return std::define_static_string(Style::transform_class(Ent));
300 return std::define_static_string(Style::transform_enum(Ent));
302 return std::define_static_string(Style::transform_enumerator(Ent));
304 return std::define_static_string(Style::transform_method(Ent));
306 return std::define_static_string(Style::transform_static_method(Ent));
308 return std::define_static_string(Style::transform_function(Ent));
310 return std::define_static_string(Style::transform_field(Ent));
312 return std::define_static_string(Style::transform_variable(Ent));
314 return std::define_static_string(Style::transform_submodule(Ent));
342template <std::meta::info Ent, lang L,
class Style, ent_kind K>
349 throw std::invalid_argument{
350 "welder: this entity has no identifier (a template instantiation?) and "
351 "no [[=welder::weld_as]] — pass an explicit name at the weld_* call"};
The core interface concepts welder's static polymorphism rests on, gathered in one catalogue: the cus...
A name style names every kind of entity welder can bind, through one hook per kind.
consteval std::string restyle(std::string_view id, case_kind kind)
Re-spell identifier id in convention kind, preserving any leading and trailing underscore run (_priva...
uniform< case_kind::camel > camel_case
fooBar everywhere
uniform< case_kind::pascal > pascal_case
FooBar everywhere
case_kind
The naming convention a joiner emits.
consteval std::vector< std::string > split_words(std::string_view id)
Split an identifier into lower-cased words, however it was spelled.
uniform< case_kind::kebab > kebab_case
foo-bar everywhere
uniform< case_kind::screaming_snake > screaming_snake_case
FOO_BAR everywhere
consteval std::string join_words(const std::vector< std::string > &words, case_kind kind)
Join already-lower-cased words in convention kind.
uniform< case_kind::snake > snake_case
foo_bar everywhere
ent_kind
The nameable entity kinds welder distinguishes, one per name-style hook — picked by the driver/rod so...
@ field
a data member → transform_field.
@ submodule
a namespace bound as a submodule → transform_submodule.
@ static_method
a static member function → transform_static_method.
@ class_
a class/struct type → transform_class.
@ function
a free function → transform_function.
@ variable
a namespace variable → transform_variable.
@ method
a member function → transform_method.
@ enumerator
an enumerator → transform_enumerator.
@ enum_
an enum type → transform_enum.
consteval const char * weld_as_of()
The verbatim weld_as name forced on Ent for language L, or nullptr.
consteval unsigned lang_bit(lang l)
The single-language bit for l within a language mask.
constexpr const char * name_of_or(const char *override_)
Resolve a bound name with a call-site override: override_ wins verbatim, nullptr falls back to name_o...
consteval const char * name_of()
The final bound name of Ent (a K-kind entity) for language L under name style Style.
The stored form of a weld_as annotation: a forced target-language name.
The identity style: bind every C++ identifier unchanged.
static consteval std::string transform_enumerator(std::meta::info e)
static consteval std::string transform_field(std::meta::info e)
static consteval std::string transform_variable(std::meta::info e)
static consteval std::string transform_method(std::meta::info e)
static consteval std::string transform_enum(std::meta::info e)
static consteval std::string id(std::meta::info e)
static consteval std::string transform_function(std::meta::info e)
static consteval std::string transform_submodule(std::meta::info e)
static consteval std::string transform_class(std::meta::info e)
static consteval std::string transform_static_method(std::meta::info e)