Skip to content

Commit f2f9519

Browse files
16bit-ykikoclaude
andauthored
feat(refl): introduce reflection layer with virtual_schema and type_info (#107)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 4a2d986 commit f2f9519

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+3145
-814
lines changed

include/eventide/common/meta.h

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -54,21 +54,9 @@ concept ge_comparable_with = requires(const L& lhs, const R& rhs) {
5454
};
5555

5656
template <typename T>
57-
struct is_optional : std::false_type {};
57+
constexpr inline bool is_optional_v = is_specialization_of<std::optional, std::remove_cvref_t<T>>;
5858

5959
template <typename T>
60-
struct is_optional<std::optional<T>> : std::true_type {};
61-
62-
template <typename T>
63-
constexpr inline bool is_optional_v = is_optional<std::remove_cvref_t<T>>::value;
64-
65-
template <typename T>
66-
struct is_expected : std::false_type {};
67-
68-
template <typename T, typename E>
69-
struct is_expected<std::expected<T, E>> : std::true_type {};
70-
71-
template <typename T>
72-
constexpr inline bool is_expected_v = is_expected<std::remove_cvref_t<T>>::value;
60+
constexpr inline bool is_expected_v = is_specialization_of<std::expected, std::remove_cvref_t<T>>;
7361

7462
} // namespace eventide

include/eventide/common/naming.h

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
#pragma once
2+
3+
#include <string>
4+
#include <string_view>
5+
6+
namespace eventide::naming {
7+
8+
constexpr bool is_lower(char c) {
9+
return c >= 'a' && c <= 'z';
10+
}
11+
12+
constexpr bool is_upper(char c) {
13+
return c >= 'A' && c <= 'Z';
14+
}
15+
16+
constexpr bool is_digit(char c) {
17+
return c >= '0' && c <= '9';
18+
}
19+
20+
constexpr bool is_alpha(char c) {
21+
return is_lower(c) || is_upper(c);
22+
}
23+
24+
constexpr bool is_alnum(char c) {
25+
return is_alpha(c) || is_digit(c);
26+
}
27+
28+
constexpr char to_lower(char c) {
29+
return is_upper(c) ? static_cast<char>(c - 'A' + 'a') : c;
30+
}
31+
32+
constexpr char to_upper(char c) {
33+
return is_lower(c) ? static_cast<char>(c - 'a' + 'A') : c;
34+
}
35+
36+
constexpr std::string normalize_to_lower_snake(std::string_view text) {
37+
std::string out;
38+
for(std::size_t i = 0; i < text.size(); ++i) {
39+
const char c = text[i];
40+
if(is_alnum(c)) {
41+
if(is_upper(c)) {
42+
const bool prev_alnum = i > 0 && is_alnum(text[i - 1]);
43+
const bool prev_lower_or_digit =
44+
i > 0 && (is_lower(text[i - 1]) || is_digit(text[i - 1]));
45+
const bool next_lower = i + 1 < text.size() && is_lower(text[i + 1]);
46+
if(!out.empty() && out.back() != '_' && prev_alnum &&
47+
(prev_lower_or_digit || next_lower)) {
48+
out += '_';
49+
}
50+
out += to_lower(c);
51+
} else {
52+
out += to_lower(c);
53+
}
54+
} else if(!out.empty() && out.back() != '_') {
55+
out += '_';
56+
}
57+
}
58+
auto start = out.find_first_not_of('_');
59+
if(start == std::string::npos)
60+
return {};
61+
auto end = out.find_last_not_of('_');
62+
return out.substr(start, end - start + 1);
63+
}
64+
65+
constexpr std::string snake_to_camel(std::string_view text, bool upper_first) {
66+
auto snake = normalize_to_lower_snake(text);
67+
std::string out;
68+
bool capitalize_next = upper_first;
69+
bool seen_output = false;
70+
for(auto c: snake) {
71+
if(c == '_') {
72+
capitalize_next = true;
73+
continue;
74+
}
75+
if(capitalize_next && is_alpha(c)) {
76+
out += to_upper(c);
77+
} else if(!seen_output) {
78+
out += upper_first ? to_upper(c) : to_lower(c);
79+
} else {
80+
out += c;
81+
}
82+
capitalize_next = false;
83+
seen_output = true;
84+
}
85+
return out;
86+
}
87+
88+
constexpr std::string snake_to_upper(std::string_view text) {
89+
auto snake = normalize_to_lower_snake(text);
90+
for(auto& c: snake)
91+
c = to_upper(c);
92+
return snake;
93+
}
94+
95+
namespace rename_policy {
96+
97+
struct identity {
98+
std::string operator()(bool, std::string_view value) const {
99+
return std::string(value);
100+
}
101+
};
102+
103+
struct lower_snake {
104+
std::string operator()(bool, std::string_view value) const {
105+
return normalize_to_lower_snake(value);
106+
}
107+
};
108+
109+
struct lower_camel {
110+
std::string operator()(bool is_serialize, std::string_view value) const {
111+
if(is_serialize) {
112+
return snake_to_camel(value, false);
113+
}
114+
return normalize_to_lower_snake(value);
115+
}
116+
};
117+
118+
struct upper_camel {
119+
std::string operator()(bool is_serialize, std::string_view value) const {
120+
if(is_serialize) {
121+
return snake_to_camel(value, true);
122+
}
123+
return normalize_to_lower_snake(value);
124+
}
125+
};
126+
127+
struct upper_snake {
128+
std::string operator()(bool is_serialize, std::string_view value) const {
129+
if(is_serialize) {
130+
return snake_to_upper(value);
131+
}
132+
return normalize_to_lower_snake(value);
133+
}
134+
};
135+
136+
using upper_case = upper_snake;
137+
138+
} // namespace rename_policy
139+
140+
} // namespace eventide::naming
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
#pragma once
2+
3+
#include <cstddef>
4+
#include <tuple>
5+
#include <type_traits>
6+
7+
#include "meta.h"
8+
9+
namespace eventide {
10+
11+
namespace detail {
12+
13+
template <template <typename> class Pred, typename... Ts>
14+
constexpr bool pack_any_v = (Pred<Ts>::value || ...);
15+
16+
template <template <typename> class Pred>
17+
constexpr bool pack_any_v<Pred> = false;
18+
19+
template <template <typename> class Pred, typename... Ts>
20+
constexpr std::size_t pack_count_v = (static_cast<std::size_t>(Pred<Ts>::value) + ...);
21+
22+
template <template <typename> class Pred>
23+
constexpr std::size_t pack_count_v<Pred> = 0;
24+
25+
template <template <typename> class Pred, typename... Ts>
26+
struct pack_find {
27+
using type = void;
28+
};
29+
30+
template <template <typename> class Pred, typename First, typename... Rest>
31+
struct pack_find<Pred, First, Rest...> {
32+
using type =
33+
std::conditional_t<Pred<First>::value, First, typename pack_find<Pred, Rest...>::type>;
34+
};
35+
36+
template <template <typename...> typename HKT, typename... Ts>
37+
struct pack_find_spec {
38+
using type = void;
39+
};
40+
41+
template <template <typename...> typename HKT, typename First, typename... Rest>
42+
struct pack_find_spec<HKT, First, Rest...> {
43+
using type = std::conditional_t<is_specialization_of<HKT, First>,
44+
First,
45+
typename pack_find_spec<HKT, Rest...>::type>;
46+
};
47+
48+
} // namespace detail
49+
50+
template <typename Tuple, template <typename> class Pred>
51+
constexpr bool tuple_any_of_v = false;
52+
53+
template <template <typename> class Pred, typename... Ts>
54+
constexpr bool tuple_any_of_v<std::tuple<Ts...>, Pred> = detail::pack_any_v<Pred, Ts...>;
55+
56+
template <typename Tuple, typename Tag>
57+
constexpr bool tuple_has_v = false;
58+
59+
template <typename Tag, typename... Ts>
60+
constexpr bool tuple_has_v<std::tuple<Ts...>, Tag> = (std::is_same_v<Ts, Tag> || ...);
61+
62+
template <typename Tuple, template <typename...> typename HKT>
63+
constexpr bool tuple_has_spec_v = false;
64+
65+
template <template <typename...> typename HKT, typename... Ts>
66+
constexpr bool tuple_has_spec_v<std::tuple<Ts...>, HKT> = (is_specialization_of<HKT, Ts> || ...);
67+
68+
template <typename Tuple, template <typename> class Pred>
69+
constexpr std::size_t tuple_count_of_v = 0;
70+
71+
template <template <typename> class Pred, typename... Ts>
72+
constexpr std::size_t tuple_count_of_v<std::tuple<Ts...>, Pred> = detail::pack_count_v<Pred, Ts...>;
73+
74+
template <typename Tuple, template <typename> class Pred>
75+
struct tuple_find;
76+
77+
template <template <typename> class Pred, typename... Ts>
78+
struct tuple_find<std::tuple<Ts...>, Pred> : detail::pack_find<Pred, Ts...> {};
79+
80+
template <typename Tuple, template <typename> class Pred>
81+
using tuple_find_t = typename tuple_find<Tuple, Pred>::type;
82+
83+
template <typename Tuple, template <typename...> typename HKT>
84+
struct tuple_find_spec;
85+
86+
template <template <typename...> typename HKT, typename... Ts>
87+
struct tuple_find_spec<std::tuple<Ts...>, HKT> : detail::pack_find_spec<HKT, Ts...> {};
88+
89+
template <typename Tuple, template <typename...> typename HKT>
90+
using tuple_find_spec_t = typename tuple_find_spec<Tuple, HKT>::type;
91+
92+
} // namespace eventide

include/eventide/common/type_list.h

Lines changed: 52 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22

33
#include <concepts>
4+
#include <cstddef>
45
#include <type_traits>
56

67
namespace eventide {
@@ -19,29 +20,6 @@ struct type_list_prepend<type_list<Ts...>, T> {
1920
template <typename List, typename T>
2021
using type_list_prepend_t = typename type_list_prepend<List, T>::type;
2122

22-
template <typename List, typename T>
23-
struct type_list_append;
24-
25-
template <typename... Ts, typename T>
26-
struct type_list_append<type_list<Ts...>, T> {
27-
using type = type_list<Ts..., T>;
28-
};
29-
30-
template <typename List, typename T>
31-
using type_list_append_t = typename type_list_append<List, T>::type;
32-
33-
template <typename List, typename T>
34-
struct type_list_append_unique;
35-
36-
template <typename... Ts, typename T>
37-
struct type_list_append_unique<type_list<Ts...>, T> {
38-
using type =
39-
std::conditional_t<(std::same_as<T, Ts> || ...), type_list<Ts...>, type_list<Ts..., T>>;
40-
};
41-
42-
template <typename List, typename T>
43-
using type_list_append_unique_t = typename type_list_append_unique<List, T>::type;
44-
4523
template <typename List, typename T>
4624
struct type_list_contains;
4725

@@ -72,17 +50,6 @@ struct type_list_filter<type_list<T, Ts...>, Predicate> {
7250
template <typename List, template <typename> typename Predicate>
7351
using type_list_filter_t = typename type_list_filter<List, Predicate>::type;
7452

75-
template <typename List, template <typename> typename Mapper>
76-
struct type_list_transform;
77-
78-
template <template <typename> typename Mapper, typename... Ts>
79-
struct type_list_transform<type_list<Ts...>, Mapper> {
80-
using type = type_list<typename Mapper<Ts>::type...>;
81-
};
82-
83-
template <typename List, template <typename> typename Mapper>
84-
using type_list_transform_t = typename type_list_transform<List, Mapper>::type;
85-
8653
template <typename List>
8754
struct type_list_unique;
8855

@@ -118,15 +85,59 @@ struct type_list_unique<type_list<Ts...>> {
11885
template <typename List>
11986
using type_list_unique_t = typename type_list_unique<List>::type;
12087

121-
template <typename List, template <typename...> typename Target>
122-
struct type_list_apply;
88+
template <std::size_t I, typename List>
89+
struct type_list_element;
12390

124-
template <typename... Ts, template <typename...> typename Target>
125-
struct type_list_apply<type_list<Ts...>, Target> {
126-
using type = Target<Ts...>;
91+
template <std::size_t I, typename First, typename... Rest>
92+
struct type_list_element<I, type_list<First, Rest...>> :
93+
type_list_element<I - 1, type_list<Rest...>> {};
94+
95+
template <typename First, typename... Rest>
96+
struct type_list_element<0, type_list<First, Rest...>> {
97+
using type = First;
12798
};
12899

129-
template <typename List, template <typename...> typename Target>
130-
using type_list_apply_t = typename type_list_apply<List, Target>::type;
100+
template <std::size_t I, typename List>
101+
using type_list_element_t = typename type_list_element<I, List>::type;
102+
103+
template <typename A, typename B>
104+
struct type_list_cat;
105+
106+
template <typename... As, typename... Bs>
107+
struct type_list_cat<type_list<As...>, type_list<Bs...>> {
108+
using type = type_list<As..., Bs...>;
109+
};
110+
111+
template <typename A, typename B>
112+
using type_list_cat_t = typename type_list_cat<A, B>::type;
113+
114+
template <typename... Lists>
115+
struct type_list_concat;
116+
117+
template <>
118+
struct type_list_concat<> {
119+
using type = type_list<>;
120+
};
121+
122+
template <typename List>
123+
struct type_list_concat<List> {
124+
using type = List;
125+
};
126+
127+
template <typename First, typename Second, typename... Rest>
128+
struct type_list_concat<First, Second, Rest...> :
129+
type_list_concat<type_list_cat_t<First, Second>, Rest...> {};
130+
131+
template <typename... Lists>
132+
using type_list_concat_t = typename type_list_concat<Lists...>::type;
133+
134+
template <typename List>
135+
struct type_list_size;
136+
137+
template <typename... Ts>
138+
struct type_list_size<type_list<Ts...>> : std::integral_constant<std::size_t, sizeof...(Ts)> {};
139+
140+
template <typename List>
141+
constexpr inline std::size_t type_list_size_v = type_list_size<List>::value;
131142

132143
} // namespace eventide

0 commit comments

Comments
 (0)