7#include "ll/api/base/Concepts.h"
8#include "ll/api/base/Meta.h"
9#include "ll/api/reflection/TypeName.h"
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("."))
17#include "boost/pfr.hpp"
19#include "magic_enum/magic_enum.hpp"
21namespace ll::reflection {
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>>;
30constexpr auto const member_name_array_v = boost::pfr::names_as_array<std::remove_cvref_t<T>>();
33constexpr auto const member_count_v = boost::pfr::tuple_size_v<T>;
35template <
size_t I,
class T>
36using member_t =
typename boost::pfr::tuple_element_t<I, T>;
40 template <
size_t S,
size_t A>
42 alignas(A)
char storage[S];
44 template <
class... Ts>
45 using AlignedTuple = boost::pfr::detail::sequence_tuple::tuple<
AlignedStorage<
sizeof(Ts),
alignof(Ts)>...>;
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]);
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>>());
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));
Definition Reflection.h:27
Definition Reflection.h:41
Definition Reflection.h:39