14export import :type_name;
15export import :accessors;
16export import :equality;
37 return static_cast<char *
>(obj) +
offset;
42 return *
static_cast<T *
>(
get_ptr(obj));
45 template <
typename MetadataType>
48 for (
const auto & [tif, ptr] :
metadata) {
56 template <
typename MetadataType>
59 for (
const auto & [tif, ptr] :
metadata) {
61 return *
static_cast<const MetadataType*
>(ptr);
64 throw std::runtime_error(
"Could not find metadata type");
69 friend std::hash<refl::field_path>;
72 field_path(std::initializer_list<const field_info*> fields): fields_(fields) { }
75 return fields_.back()->type();
82 ptr =
field->get_ptr(ptr);
90 return *
static_cast<T *
>(
get_ptr(obj));
94 return fields_ == other.fields_;
97 std::vector<const field_info*> fields_;
106 export template <
typename T>
112 template <
template <
typename...>
typename Pack,
typename... Args>
114 static std::vector<type_id_t>
vector();
116 template <
template <
typename, std::
size_t>
typename Pack,
typename T, std::size_t I>
118 static std::vector<type_id_t>
vector();
123 template <
typename Type>
128 template <
typename Field>
131 .index = Field::index,
134 .offset = Field::offset,
135 .access_type = Field::access,
136 .type_id = Field::type_id,
137 .type = &type_getter<typename Field::type>,
139 field.metadata.reserve(Field::metadata_count);
141 [&]<std::size_t... I>(std::index_sequence<I...>) {
142 (
field.metadata.emplace_back(
143 &type_getter<
typename Field::template metadata_type<I> >,
144 static_cast<void*
>(
new std::remove_const_t<
typename Field::template metadata_type<I>>{Field::template metadata_item<I>})), ...);
145 }(std::make_index_sequence<Field::metadata_count>{});
150 template <
typename Field>
152 fields_.push_back(make_field_data<Field>());
153 const auto&
field = fields_.back();
159 template <
typename Method>
163 .index = Method::index,
164 .name = Method::name,
165 .access_type = Method::access,
167 const auto&
method = methods_.back();
173 template <
typename T>
175 using type = std::remove_const_t<std::remove_reference_t<T>>;
189 [&]<std::size_t... I>(std::index_sequence<I...>) {
191 }(std::make_index_sequence<f_count>{});
193 [&]<std::size_t... I>(std::index_sequence<I...>) {
195 }(std::make_index_sequence<m_count>{});
204 if constexpr (std::is_const_v<T>) {
208 if constexpr (std::is_lvalue_reference_v<T>) {
209 ti.is_lval_ref_ =
true;
211 }
else if constexpr (std::is_rvalue_reference_v<T>) {
212 ti.is_rval_ref_ =
true;
214 }
else if constexpr (std::is_pointer_v<T>) {
219 if constexpr (pid != 0) {
224 if constexpr(std::is_copy_constructible_v<type>) {
225 ti.copy_construct_function_ = [](
const void* src) ->
void* {
226 const type& src_ref = *
static_cast<const type*
>(src);
227 type* dest =
new type(src_ref);
231 if constexpr(std::is_copy_assignable_v<type>) {
232 ti.copy_assign_function_ = [](
void* dest,
const void* src) {
233 type& dest_ref = *
static_cast<type*
>(dest);
234 const type& src_ref = *
static_cast<const type*
>(src);
239 ti.equality_function_ = [](
const void* lhs,
const void* rhs) {
240 const type& LHS = *
static_cast<const type*
>(lhs);
241 const type& RHS = *
static_cast<const type*
>(rhs);
244 }
else if constexpr (std::equality_comparable<type> and not std::is_function_v<type>) {
245 ti.equality_function_ = [](
const void* lhs,
const void* rhs) {
246 const type& LHS = *
static_cast<const type*
>(lhs);
247 const type& RHS = *
static_cast<const type*
>(rhs);
255 const std::string&
name()
const {
264 if (fields_by_name_.contains(
name)) {
265 return fields_by_name_.at(
name);
270 if (fields_by_offset_.contains(offset)) {
271 return fields_by_offset_.at(offset);
279 std::size_t
id()
const {
283 template <
typename T>
286 return type_id_ == tid;
289 template <
template <
typename...>
typename Pack>
292 return pack_id_ == pid;
295 template <
template <
typename T, std::
size_t S>
typename Pack>
298 return pack_id_ == pid;
306 return indirect_type_id_.has_value();
319 if (indirect_type_id_.has_value()) {
327 std::vector<const type_info*> tis{};
328 for (
const auto& tid: pack_param_ids_) {
335 if (copy_construct_function_.has_value()) {
336 return copy_construct_function_.value()(ptr);
342 if (copy_assign_function_.has_value()) {
343 copy_assign_function_.value()(dest, src);
347 bool equality(
const void* lhs,
const void* rhs)
const {
348 if (equality_function_.has_value()) {
349 return equality_function_.value()(lhs, rhs);
356 std::list<field_info> fields_{};
357 std::unordered_map<std::string, const field_info*> fields_by_name_{};
358 std::unordered_map<std::size_t, const field_info*> fields_by_offset_{};
359 std::list<method_info> methods_{};
360 std::unordered_map<std::string, const method_info*> methods_by_name_{};
362 bool is_const_ =
false;
363 bool is_lval_ref_ =
false;
364 bool is_rval_ref_ =
false;
365 bool is_ptr_ =
false;
368 std::optional<type_id_t> indirect_type_id_{std::nullopt};
370 std::vector<type_id_t> pack_param_ids_{};
373 std::optional<std::function<
void*(
const void*)>> copy_construct_function_{std::nullopt};
375 std::optional<std::function<void(
void*,
const void*)>> copy_assign_function_{std::nullopt};
377 std::optional<std::function<bool(
const void*,
const void*)>> equality_function_{std::nullopt};
381 template <
template <
typename...>
typename Pack,
typename... Args>
383 std::vector<type_id_t> ids{};
387 template <
template <
typename, std::
size_t>
typename Pack,
typename T, std::size_t I>
389 std::vector<type_id_t> ids{};
402struct std::hash<
refl::field_path> {
404 std::size_t seed = path.fields_.size();
405 for (
const auto &v: path.fields_) {
406 seed ^= std::hash<std::size_t>{}(
reinterpret_cast<std::size_t
>(v)) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
bool is_pack_1t1i() const
std::optional< const field_info * > field_by_name(const std::string &name) const
std::vector< const type_info * > pack_parameter_types() const
const std::string & name() const
const auto & fields() const
bool equality(const void *lhs, const void *rhs) const
void * make_copy_of(const void *ptr) const
std::size_t hash_code() const
void assign_copy_of(const void *src, void *dest) const
std::optional< const field_info * > field_by_offset(const std::size_t &offset) const
static const type_info & from()
const type_info & indirect_type() const
constexpr type_id_t pack_1t1i_id
constexpr type_id_t type_id
std::map< type_id_t, type_info > type_registry
bool deep_eq(const R &lhs, const R &rhs)
constexpr std::size_t field_count
type_id_t get_id_from_info_getter(const type_info &(*tif)())
constexpr type_id_t pack_type_id
constexpr type_id_t pack_id
constexpr std::size_t method_count
const MetadataType & get_metadata() const
void * get_ptr(void *obj) const
T & get_ref(void *obj) const
bool has_metadata() const
std::vector< std::pair< const type_info &(*)(), void * > > metadata
void * get_ptr(void *obj) const
T & get_ref(void *obj) const
field_path(const field_info *field)
const type_info & type() const
field_path(std::initializer_list< const field_info * > fields)
bool operator==(const field_path &other) const
static constexpr const char * name
static constexpr std::size_t offset
static std::vector< type_id_t > vector()
static std::vector< type_id_t > vector()
static std::vector< type_id_t > vector()
static constexpr const char * name
std::size_t operator()(const refl::field_path &path) const