LeviLamina
Loading...
Searching...
No Matches
Reflection.h
1#pragma once
2
3#include <cstddef>
4#include <type_traits>
5#include <utility>
6
7#include "ll/api/base/Concepts.h"
8#include "ll/api/base/Meta.h"
9#include "ll/api/reflection/TypeName.h"
10
11#if defined(__clang__) && !defined(BOOST_PFR_CORE_NAME_PARSING)
12#define BOOST_PFR_CORE_NAME_PARSING \
13 (sizeof("auto boost::pfr::detail::name_of_field_impl() [MsvcWorkaround = ") - 1, sizeof("}]") - 1, backward("."))
14
15#endif
16
17#include "boost/pfr.hpp"
18
19#include "magic_enum/magic_enum.hpp"
20
21namespace ll::reflection {
22template <class T>
23constexpr bool is_reflectable_v =
24 std::is_aggregate_v<std::remove_cvref_t<T>> && !traits::is_std_array_v<std::remove_cvref_t<T>>;
25
26template <class T>
27concept Reflectable = is_reflectable_v<T>;
28
29template <class T>
30constexpr auto const member_name_array_v = boost::pfr::names_as_array<std::remove_cvref_t<T>>();
31
32template <class T>
33constexpr auto const member_count_v = boost::pfr::tuple_size_v<T>;
34
35template <size_t I, class T>
36using member_t = typename boost::pfr::tuple_element_t<I, T>;
37
38template <class T>
40 template <size_t S, size_t A>
42 alignas(A) char storage[S];
43 };
44 template <class... Ts>
45 using AlignedTuple = boost::pfr::detail::sequence_tuple::tuple<AlignedStorage<sizeof(Ts), alignof(Ts)>...>;
46
47 template <size_t I, size_t... Ns>
48 static ptrdiff_t offset(std::index_sequence<Ns...>) noexcept {
49 AlignedTuple<member_t<Ns, T>...> layout{};
50 return static_cast<char const*>(&get<I>(layout).storage[0])
51 - static_cast<char const*>(&get<0>(layout).storage[0]);
52 }
53};
54
55template <size_t I, class T>
56inline auto const member_offset_v = OffsetGetter<T>::template offset<I>(std::make_index_sequence<member_count_v<T>>());
57
58template <Reflectable T, class F>
59constexpr void forEachMember(T&& value, F&& func) {
60 boost::pfr::for_each_field(std::forward<T>(value), [func = std::forward<F>(func)](auto&& field, std::size_t idx) {
61 func(member_name_array_v<T>[idx], std::forward<decltype((field))>(field));
62 });
63}
64} // namespace ll::reflection
Definition Reflection.h:27
Definition Reflection.h:39