cpp-reflect
C++ Reflection and Annotations Library
Loading...
Searching...
No Matches
accessors.cppm
Go to the documentation of this file.
1// Copyright (c) 2024-2025, Víctor Castillo Agüero.
2// SPDX-License-Identifier: GPL-3.0-or-later
3
8
9export module reflect:accessors;
10
11import std;
12
13import packtl;
14
15import :types;
16import :type_name;
17
18template <typename Type, std::size_t Offset>
20 unsigned char offset_[Offset];
21 Type value;
22};
23
24template <typename Type>
25struct representation<Type, 0> {
26 Type value;
27};
28
29
30export namespace refl {
31
32 enum class access_spec : unsigned char {
33 NONE = 0U,
34 PRIVATE = 1U,
36 PUBLIC = 3U,
37 };
38
39 template <refl::Reflected T, std::size_t I>
40 struct field {
41 static constexpr std::size_t index = I;
42 static constexpr const char* name = static_type_info<T>::field_names[I];
43 using type = typename packtl::get<I, typename static_type_info<T>::field_types>::type;
45 static constexpr std::size_t size =
46 packtl::get<I, typename static_type_info<T>::field_sizes>::value;
47 static constexpr std::size_t offset =
48 packtl::get<I, typename static_type_info<T>::field_offsets>::value;
49 static constexpr access_spec access =
50 access_spec{packtl::get<I, typename static_type_info<T>::field_access_specifiers>::value};
51
52 static constexpr bool is_reference = std::is_reference_v<type>;
53 static constexpr bool is_pointer = std::is_pointer_v<type>;
54
55 static constexpr std::size_t metadata_offset =
56 packtl::get<I, typename static_type_info<T>::field_metadata_offsets>::value;
57 static constexpr std::size_t metadata_count =
58 packtl::get<I, typename static_type_info<T>::field_metadata_counts>::value;
59
60 template <std::size_t J>
61 requires(J < metadata_count)
62 using metadata_type = typename std::
63 tuple_element<metadata_offset + J, decltype(static_type_info<T>::field_metadata)>::type;
64
65 template <std::size_t J>
66 requires(J < metadata_count)
67 static constexpr decltype(std::get<metadata_offset + J>(static_type_info<T>::field_metadata)
68 ) metadata_item = std::get<metadata_offset + J>(static_type_info<T>::field_metadata);
69
70 template <typename MetadataType>
71 static constexpr bool has_metadata = []<std::size_t... J>(std::index_sequence<J...>) -> bool {
72 if constexpr ((std::same_as<const MetadataType, metadata_type<J>> or ...)) {
73 return true;
74 } else {
75 return false;
76 }
77 }(std::make_index_sequence<metadata_count>{});
78
79 template <typename MetadataType, std::size_t StartFrom>
80 requires(not has_metadata<MetadataType>)
81 static int find_metadata() {
82 return 0;
83 }
84
85 template <typename MetadataType, std::size_t StartFrom>
86 requires(has_metadata<MetadataType> and StartFrom < metadata_count)
87 static consteval MetadataType find_metadata() {
88 if constexpr (std::same_as<const MetadataType, metadata_type<StartFrom>>) {
90 } else {
92 }
93 }
94
95 template <typename MetadataType>
96 static constexpr MetadataType get_metadata = find_metadata<MetadataType, 0>();
97
98 static const std::remove_reference_t<type>& from_instance(const T& instance) {
99 const auto* rep = reinterpret_cast<const representation<type, offset>*>(&instance);
100 return rep->value;
101 }
102
103 static std::remove_reference_t<type>& from_instance(T& instance) {
104 auto* rep = reinterpret_cast<representation<type, offset>*>(&instance);
105 return rep->value;
106 }
107 };
108
109 template <refl::Reflected T>
110 constexpr std::size_t field_count =
111 packtl::get_size<typename static_type_info<T>::field_types>::value;
112
113 template <refl::Reflected T, std::size_t I>
114 constexpr decltype(std::get<I>(static_type_info<T>::field_metadata)) field_meta =
116
117 template <refl::Reflected T, std::size_t I>
118 struct method {
119 static constexpr std::size_t index = I;
120 static constexpr const char* name = static_type_info<T>::method_names[I];
121 using type = typename packtl::get<I, typename static_type_info<T>::method_types>::type;
122 static constexpr access_spec access =
123 access_spec{packtl::get<I, typename static_type_info<T>::method_access_specifiers>::value};
124 };
125
126 template <refl::Reflected T>
127 constexpr std::size_t method_count =
128 packtl::get_size<typename static_type_info<T>::method_types>::value;
129
130 template <Reflected R, template <Reflected, typename> typename Fun, typename... Args>
131 auto for_each_field(Args&&... args) {
132 static constexpr auto count = field_count<R>;
133
134 auto impl = [&]<std::size_t... I>(std::index_sequence<I...>) {
135 return ((Fun<R, field<R, I>>(args...)) && ...);
136 };
137
138 return impl(std::make_index_sequence<count>{});
139 }
140} // namespace refl
std::size_t type_id_t
Definition _types.cppm:30
constexpr type_id_t type_id
constexpr std::size_t field_count
auto for_each_field(Args &&... args)
typename T::__type_info__ static_type_info
Definition _types.cppm:15
constexpr decltype(std::get< I >(static_type_info< T >::field_metadata)) field_meta
constexpr std::size_t method_count
static constexpr MetadataType get_metadata
static constexpr type_id_t type_id
static constexpr std::size_t index
static std::remove_reference_t< type > & from_instance(T &instance)
static constexpr bool is_pointer
static const std::remove_reference_t< type > & from_instance(const T &instance)
static constexpr bool is_reference
static constexpr const char * name
static constexpr decltype(std::get< metadata_offset+J >(static_type_info< T >::field_metadata)) metadata_item
static constexpr bool has_metadata
typename packtl::get< I, typename static_type_info< T >::field_types >::type type
static constexpr std::size_t size
static constexpr std::size_t offset
typename std:: tuple_element< metadata_offset+J, decltype(static_type_info< T >::field_metadata)>::type metadata_type
static consteval MetadataType find_metadata()
static constexpr access_spec access
static constexpr std::size_t metadata_offset
static constexpr std::size_t metadata_count
static int find_metadata()
static constexpr const char * name
static constexpr access_spec access
typename packtl::get< I, typename static_type_info< T >::method_types >::type type
static constexpr std::size_t index
unsigned char offset_[Offset]