23 #ifndef REFL_INCLUDE_HPP
24 #define REFL_INCLUDE_HPP
33 #include <type_traits>
41 #pragma warning( disable : 4003
)
44 #if defined(__clang__
)
45 #if __has_feature
(cxx_rtti)
46 #define REFL_RTTI_ENABLED
48 #elif defined(__GNUG__)
49 #if defined(__GXX_RTTI)
50 #define REFL_RTTI_ENABLED
52 #elif defined(_MSC_VER)
54 #define REFL_RTTI_ENABLED
89 #define REFL_MAKE_CONST_STRING(CString)
90 (::refl::util::detail::copy_from_unsized<::refl::util::detail::strlen(CString)>(CString))
106 static constexpr size_t
npos =
static_cast<size_t>(-1);
109 static constexpr size_t
size = N;
143 explicit constexpr operator const char*()
const noexcept
159 constexpr const char*
c_str()
const noexcept
167 std::string
str()
const noexcept
180 template <size_t Pos, size_t Count =
npos>
183 static_assert(Pos <= N);
184 constexpr size_t NewSize = std::min(Count, N - Pos);
186 char buf[NewSize + 1]{};
187 for (size_t i = 0; i < NewSize; i++) {
188 buf[i] =
data[Pos + i];
202 constexpr auto find(
char ch, size_t pos = 0)
const noexcept
204 for (size_t i = pos; i < N; i++) {
220 constexpr auto rfind(
char ch, size_t pos =
npos)
const noexcept
222 for (size_t i = (pos ==
npos ? N - 1 : pos); i + 1 > 0; i--) {
235 template <size_t... Idx>
236 constexpr const_string(
const const_string<N>& other, std::index_sequence<Idx...>)
noexcept
237 :
data{ other.data[Idx]... }
244 template <size_t... Idx>
245 constexpr const_string(
const char(&data)[
sizeof...(Idx) + 1], std::index_sequence<Idx...>)
noexcept
246 :
data{ data[Idx]... }
280 const char str[2]{ ch,
'\0' };
289 template <size_t N, size_t M>
292 char data[N + M + 1] { };
293 for (size_t i = 0; i < N; i++)
295 for (size_t i = 0; i < M; i++)
296 data[N + i] = b.data[i];
305 template <size_t N, size_t M>
308 return a + make_const_string(b);
316 template <size_t N, size_t M>
319 return make_const_string(a) + b;
327 template <size_t N, size_t M>
330 if constexpr (N != M) {
334 for (size_t i = 0; i < M; i++) {
335 if (a.data[i] != b.data[i]) {
348 template <size_t N, size_t M>
359 template <size_t N, size_t M>
362 return a == make_const_string(b);
370 template <size_t N, size_t M>
373 return a != make_const_string(b);
381 template <size_t N, size_t M>
384 return make_const_string(a) == b;
392 template <size_t N, size_t M>
395 return make_const_string(a) != b;
399 constexpr std::ostream& operator<<(std::ostream& os,
const const_string<N>& str)
noexcept
401 return os << str.c_str();
406 constexpr size_t strlen(
const char*
const str)
408 return *str ? 1 + strlen(str + 1) : 0;
412 constexpr const_string<N> copy_from_unsized(
const char*
const str)
415 for (size_t i = 0; i < N; i++) {
416 cstr.data[i] = str[i];
440 template <
typename... Ts>
444 static constexpr intptr_t
size =
sizeof...(Ts);
447 template <
typename T>
451 static constexpr intptr_t
size = 1;
454 template <
typename T>
459 using util::const_string;
460 using util::make_const_string;
461 using util::type_list;
462 using util::type_tag;
471 namespace macro_exports
490 using namespace refl::detail::macro_exports;
504 template <
typename T>
508 struct invalid_marker{};
513 template <size_t,
typename>
517 static constexpr size_t member_count{ 0 };
523 static constexpr std::tuple<> attributes{ };
529 template <
typename T>
530 struct type_info__<
const T> :
public type_info__<T> {};
535 template <
typename T>
536 struct type_info__<
volatile T> :
public type_info__<T> {};
541 template <
typename T>
542 struct type_info__<
const volatile T> :
public type_info__<T> {};
552 template <
typename T>
553 using type_info = refl_impl::metadata::type_info__<T>;
555 template <
typename T, size_t N>
556 using member_info =
typename type_info<T>::
template member<N>;
587 class type_descriptor;
589 template <
typename, size_t>
590 class field_descriptor;
592 template <
typename, size_t>
593 class function_descriptor;
608 template <
typename T>
611 typedef std::remove_cv_t<std::remove_reference_t<T>>
type;
619 template <
typename T>
625 template <
typename T>
626 decltype(
typename refl::detail::type_info<T>::invalid_marker{}, std::false_type{}) is_reflectable_test(
int);
629 template <
typename T>
630 std::true_type is_reflectable_test(...);
641 template <
typename T>
652 template <
typename T>
653 [[maybe_unused]]
static constexpr bool is_reflectable_v{ is_reflectable<T>::value };
658 template <
typename U>
659 [[maybe_unused]]
static auto is_container_test(
int) ->
decltype(std::declval<U>().begin(), std::declval<U>().end(), std::true_type{});
662 template <
typename U>
663 [[maybe_unused]]
static std::false_type is_container_test(...);
669 template <
typename T>
677 template <
typename T>
678 [[maybe_unused]]
static constexpr bool is_container_v{ is_container<T>::value };
682 template <size_t N,
typename... Ts>
688 static_assert(N > 0,
"Missing arguments list for get<N, Ts...>!");
691 template <size_t N,
typename T,
typename... Ts>
692 struct get<N, T, Ts...> :
public get<N - 1, Ts...>
696 template <
typename T,
typename... Ts>
697 struct get<0, T, Ts...>
702 template <size_t N,
typename...>
705 template <size_t N,
typename T,
typename... Ts>
706 struct skip<N, T, Ts...> : skip<N - 1, Ts...>
710 template <
typename T,
typename... Ts>
711 struct skip<0, T, Ts...>
724 template <size_t,
typename>
736 template <size_t N,
typename... Ts>
745 template <size_t N,
typename TypeList>
746 using get_t =
typename get<N, TypeList>::type;
749 template <size_t,
typename>
761 template <size_t N,
typename... Ts>
762 struct skip<N,
type_list<Ts...>> : detail::skip<N, Ts...>
770 template <size_t N,
typename TypeList>
771 using skip_t =
typename skip<N, TypeList>::type;
786 template <
template <
typename...>
typename T,
typename... Ts>
787 struct as_type_list<T<Ts...>>
793 template <
typename T>
794 struct as_type_list : as_type_list<remove_qualifiers_t<T>>
804 template <
typename T>
805 using as_type_list_t =
typename as_type_list<T>::type;
820 template <
template <
typename...>
typename T,
typename... Ts>
821 struct as_tuple<T<Ts...>>
823 typedef std::tuple<Ts...>
type;
827 template <
typename T>
828 struct as_tuple : as_tuple<remove_qualifiers_t<T>>
838 template <
typename T>
839 using as_tuple_t =
typename as_tuple<T>::type;
844 template <
typename TypeList>
845 using first = get<0, TypeList>;
851 template <
typename TypeList>
852 using first_t =
typename first<TypeList>::type;
857 template <
typename TypeList>
858 using last = get<TypeList::size - 1, TypeList>;
864 template <
typename TypeList>
865 using last_t =
typename last<TypeList>::type;
870 template <
typename TypeList>
871 using tail = skip<1, TypeList>;
877 template <
typename TypeList>
878 using tail_t =
typename tail<TypeList>::type;
882 template <
typename, size_t,
typename>
885 template <
typename... Us>
891 template <
typename... Us,
typename T,
typename... Ts>
897 template <size_t N,
typename... Us,
typename T,
typename... Ts>
907 template <size_t N,
typename TypeList>
913 template <size_t N,
typename TypeList>
914 using take_t =
typename take<N, TypeList>::type;
919 template <
typename TypeList>
920 using init = take<TypeList::size - 1, TypeList>;
926 template <
typename TypeList>
927 using init_t =
typename init<TypeList>::type;
931 template <
typename,
typename>
934 template <
typename... Us>
940 template <
typename... Us,
typename T,
typename... Ts>
954 template <
typename TypeList>
963 template <
typename TypeList>
964 using reverse_t =
typename reverse<TypeList>::type;
973 template <
typename...>
984 template <
typename... Ts>
994 template <
typename... Ts,
typename... Us>
1004 template <
typename TypeList1,
typename TypeList2,
typename... TypeLists>
1005 struct concat<TypeList1, TypeList2, TypeLists...> : concat<
typename concat<TypeList1, TypeList2>::type, TypeLists...>
1013 template <
typename... Ts>
1014 using concat_t =
typename concat<Ts...>::type;
1019 template <
typename T,
typename TypeList>
1028 template <
typename T,
typename TypeList>
1029 using append_t =
typename append<T, TypeList>::type;
1031 template <
typename,
typename>
1037 template <
typename T,
typename TypeList>
1038 struct prepend : concat<
type_list<T>, TypeList>
1046 template <
typename T,
typename TypeList>
1047 using prepend_t =
typename prepend<T, TypeList>::type;
1051 template <
template<
typename>
typename,
typename...>
1054 template <
template<
typename>
typename Predicate>
1055 struct filter_impl<Predicate>
1060 template <
template<
typename>
typename Predicate,
typename Head,
typename... Tail>
1061 struct filter_impl<Predicate, Head, Tail...>
1063 using type = std::conditional_t<Predicate<Head>::value,
1064 prepend_t<Head,
typename filter_impl<Predicate, Tail...>::type>,
1065 typename filter_impl<Predicate, Tail...>::type
1069 template <
template<
typename>
typename,
typename...>
1072 template <
template<
typename>
typename Mapper>
1073 struct map_impl<Mapper>
1078 template <
template<
typename>
typename Mapper,
typename Head,
typename ...Tail>
1079 struct map_impl<Mapper, Head, Tail...>
1081 using type =
typename prepend<
typename Mapper<Head>::type,
1082 typename map_impl<Mapper, Tail...>::type>::type;
1087 template <
template<
typename>
typename,
typename>
1097 template <
template<
typename>
typename Predicate,
typename... Ts>
1100 using type =
typename detail::filter_impl<Predicate, Ts...>::type;
1108 template <
template<
typename>
typename Predicate,
typename TypeList>
1109 using filter_t =
typename filter<Predicate, TypeList>::type;
1112 template <
template<
typename>
typename,
typename>
1122 template <
template<
typename>
typename Mapper,
typename... Ts>
1125 using type =
typename detail::map_impl<Mapper, Ts...>::type;
1133 template <
template<
typename>
typename Mapper,
typename... Ts>
1134 using map_t =
typename map<Mapper, Ts...>::type;
1138 template <
typename T>
1139 struct is_instance :
public std::false_type {};
1141 template <
template<
typename...>
typename T,
typename... Args>
1142 struct is_instance<T<Args...>> :
public std::true_type {};
1154 template <
typename T>
1163 template <
typename T>
1164 [[maybe_unused]]
static constexpr bool is_instance_v{ is_instance<T>::value };
1172 template <
typename T,
template<
typename...>
typename U,
typename... Args>
1173 struct is_same_template
1175 template <
template<
typename...>
typename V,
typename = V<Args...>>
1176 static auto test(
int) -> std::is_same<V<Args...>, T>;
1178 template <
template<
typename...>
typename V>
1179 static std::false_type test(...);
1181 static constexpr bool value{
decltype(test<U>(0))::value};
1184 template <
template<
typename...>
typename T,
typename U>
1185 struct is_instance_of :
public std::false_type {};
1187 template <
template<
typename...>
typename T,
template<
typename...>
typename U,
typename... Args>
1188 struct is_instance_of<T, U<Args...>> :
public is_same_template<U<Args...>, T, Args...>
1203 template <
template<
typename...>
typename T,
typename U>
1212 template <
template<
typename...>
typename T,
typename U>
1213 [[maybe_unused]]
static constexpr bool is_instance_of_v{ is_instance_of<T, U>::value };
1216 template <
typename,
typename>
1228 template <
typename T,
typename... Ts>
1229 struct contains<T,
type_list<Ts...>> : std::disjunction<std::is_same<std::remove_cv_t<T>, std::remove_cv_t<Ts>>...>
1237 template <
typename T,
typename TypeList>
1238 [[maybe_unused]]
static constexpr bool contains_v = contains<T, TypeList>::value;
1241 template <
template<
typename...>
typename,
typename>
1242 struct contains_instance;
1253 template <
template<
typename...>
typename T,
typename... Ts>
1262 template <
template<
typename...>
typename T,
typename TypeList>
1263 [[maybe_unused]]
static constexpr bool contains_instance_v = contains_instance<T, TypeList>::value;
1266 template <
typename,
typename>
1267 struct contains_base;
1281 template <
typename T,
typename... Ts>
1282 struct contains_base<T,
type_list<Ts...>> : std::disjunction<std::is_base_of<std::remove_cv_t<T>, std::remove_cv_t<Ts>>...>
1290 template <
typename T,
typename TypeList>
1291 [[maybe_unused]]
static constexpr bool contains_base_v = contains_base<T, TypeList>::value;
1295 template <
typename,
typename>
1298 template <
typename UniqueList>
1299 struct unique_impl<UniqueList,
type_list<>>
1301 using type = UniqueList;
1304 template <
typename UniqueList,
typename T,
typename... Ts>
1305 struct unique_impl<UniqueList,
type_list<T, Ts...>> :
1306 std::conditional_t<contains_v<T, UniqueList>,
1307 unique_impl<UniqueList,
type_list<Ts...>>,
1308 unique_impl<append_t<T, UniqueList>,
type_list<Ts...>>>
1320 template <
typename T>
1328 template <
typename T>
1339 template <
typename T =
int,
typename... Ts>
1349 template <
typename T>
1352 return std::forward<T>(t);
1358 template <
typename T>
1367 template <
typename T>
1378 template <
typename T,
typename... Ts>
1379 constexpr std::array<T,
sizeof...(Ts)>
to_array(
const std::tuple<Ts...>& tuple)
noexcept
1381 return std::apply([](
auto&& ... args) -> std::array<T,
sizeof...(Ts)> {
return { std::forward<
decltype(args)>(args)... }; }, tuple);
1388 template <
typename T>
1389 constexpr std::array<T, 0> to_array(
const std::tuple<>&)
noexcept
1396 template <
typename T, size_t... Idx>
1397 constexpr auto to_tuple([[maybe_unused]]
const std::array<T,
sizeof...(Idx)>& array, std::index_sequence<Idx...>)
noexcept
1399 if constexpr (
sizeof...(Idx) == 0)
return std::tuple<>{};
1400 else return std::make_tuple(std::get<Idx>(array)...);
1407 template <
typename T, size_t N>
1408 constexpr auto to_tuple(
const std::array<T, N>& array)
noexcept
1410 return detail::to_tuple<T>(array, std::make_index_sequence<N>{});
1417 template <
typename... Ts>
1420 static_assert((... && std::is_trivial_v<Ts>),
"Non-trivial types in type_list as not allowed!");
1427 template <
typename... Ts>
1435 template <
typename F,
typename... Carry>
1436 constexpr auto eval_in_order_to_tuple(
type_list<>, std::index_sequence<>, F&&, Carry&&... carry)
1438 if constexpr (
sizeof...(Carry) == 0)
return std::tuple<>{};
1439 else return std::make_tuple(std::forward<Carry>(carry)...);
1446 template <
typename F,
typename T,
typename... Ts, size_t I, size_t... Idx,
typename... Carry>
1447 constexpr auto eval_in_order_to_tuple(
type_list<T, Ts...>, std::index_sequence<I, Idx...>, F&& f, Carry&&... carry)
1449 static_assert(std::is_trivial_v<T>,
"Argument is a non-trivial type!");
1451 if constexpr (std::is_invocable_v<F, T, size_t>) {
1452 return eval_in_order_to_tuple(
1454 std::index_sequence<Idx...>{},
1456 std::forward<Carry>(carry)...,
1461 return eval_in_order_to_tuple(
1463 std::index_sequence<Idx...>{},
1465 std::forward<Carry>(carry)...,
1483 template <
typename F,
typename... Ts>
1486 return detail::eval_in_order_to_tuple(list, std::make_index_sequence<
sizeof...(Ts)>{}, std::forward<F>(f));
1500 template <
typename T,
typename F,
typename... Ts>
1503 return to_array<T>(map_to_tuple(list, std::forward<F>(f)));
1516 template <
typename F,
typename... Ts>
1519 map_to_tuple(list, [&](
auto&&... args) ->
decltype(f(std::forward<
decltype(args)>(args)...), 0)
1521 f(std::forward<
decltype(args)>(args)...);
1530 template <
typename R,
typename F,
typename... Ts>
1531 constexpr R accumulate(
type_list<>, F&&, R&& initial_value)
1533 return std::forward<R>(initial_value);
1542 template <
typename R,
typename F,
typename T,
typename... Ts>
1545 static_assert(std::is_trivial_v<T>,
"Argument is a non-trivial type!");
1549 std::forward<std::invoke_result_t<F&&, R&&, T&&>>(
1550 f(std::forward<R>(initial_value), T {})));
1558 template <
typename F,
typename... Ts>
1561 return accumulate<size_t>(list,
1562 [&](size_t acc,
const auto& t) -> size_t {
return acc + (f(t) ? 1 : 0); },
1568 template <
typename F,
typename... Carry>
1574 template <
typename F,
typename T,
typename... Ts,
typename... Carry>
1577 static_assert(std::is_trivial_v<T>,
"Argument is a non-trivial type!");
1578 if constexpr (f(T{})) {
1598 template <
typename F,
typename... Ts>
1601 return decltype(detail::filter(std::forward<F>(f), list,
type_list<>{}))();
1608 template <
typename F,
typename... Ts>
1611 using result_list =
decltype(detail::filter(std::forward<F>(f), list,
type_list<>{}));
1612 static_assert(result_list::size != 0,
"find_first did not match anything!");
1613 return trait::get_t<0, result_list>{};
1621 template <
typename F,
typename... Ts>
1624 using result_list =
decltype(detail::filter(std::forward<F>(f), list,
type_list<>{}));
1625 static_assert(result_list::size != 0,
"find_one did not match anything!");
1626 static_assert(result_list::size == 1,
"Cannot resolve multiple matches in find_one!");
1627 return trait::get_t<0, result_list>{};
1634 template <
typename F,
typename T,
typename... Ts>
1637 using result_list =
decltype(detail::filter(std::forward<F>(f), list,
type_list<>{}));
1638 return result_list::size > 0;
1645 template <
typename T,
typename... Ts>
1655 template <
typename T,
typename... Ts>
1665 template <
template <
typename...>
typename T,
typename... Ts>
1681 template <
typename... Ts,
typename F>
1689 template <
template<
typename...>
typename T, ptrdiff_t N,
typename... Ts>
1690 constexpr ptrdiff_t index_of_template()
noexcept
1692 if constexpr (
sizeof...(Ts) <= N)
1702 return index_of_template<T, N + 1, Ts...>();
1706 template <
template<
typename...>
typename T,
typename... Ts>
1707 constexpr ptrdiff_t index_of_template()
noexcept
1709 if constexpr (!(... ||
trait::is_instance_of_v<T, Ts>))
return -1;
1710 return index_of_template<T, 0, Ts...>();
1715 template <size_t N,
typename... Ts>
1716 constexpr auto&
get(std::tuple<Ts...>& ts)
noexcept
1718 return std::get<N>(ts);
1722 template <size_t N,
typename... Ts>
1723 constexpr const auto&
get(
const std::tuple<Ts...>& ts)
noexcept
1725 return std::get<N>(ts);
1729 template <
typename T,
typename... Ts>
1730 constexpr T&
get(std::tuple<Ts...>& ts)
noexcept
1732 return std::get<T>(ts);
1736 template <
typename T,
typename... Ts>
1737 constexpr const T&
get(
const std::tuple<Ts...>& ts)
noexcept
1739 return std::get<T>(ts);
1743 template <
template<
typename...>
typename T,
typename... Ts>
1746 static_assert((... ||
trait::is_instance_of_v<T, Ts>),
"The tuple does not contain a type that is a template instance of T!");
1747 constexpr size_t idx =
static_cast<size_t>(detail::index_of_template<T, Ts...>());
1748 return std::get<idx>(ts);
1752 template <
template<
typename...>
typename T,
typename... Ts>
1755 static_assert((... ||
trait::is_instance_of_v<T, Ts>),
"The tuple does not contain a type that is a template instance of T!");
1756 constexpr size_t idx =
static_cast<size_t>(detail::index_of_template<T, Ts...>());
1757 return std::get<idx>(ts);
1767 template <
typename... Ts>
1780 template <
typename... Ts>
1867 template <
typename F>
1881 template <
typename... Ts>
1894 template <
typename... Ts>
1895 [[maybe_unused]]
static constexpr base_types<Ts...> bases{ };
1901 namespace macro_exports
1903 using attr::property;
1913 template <
typename T>
1914 auto member_type_test(
int) ->
decltype(
typename T::member_type{}, std::true_type{});
1916 template <
typename T>
1917 std::false_type member_type_test(...);
1923 template <
typename T>
1931 template <
typename T>
1932 [[maybe_unused]]
static constexpr bool is_member_v{ is_member<T>::value };
1936 template <
typename T>
1937 struct is_field_2 : std::is_base_of<
typename T::member_type,
member::
field>
1945 template <
typename T>
1953 template <
typename T>
1954 [[maybe_unused]]
static constexpr bool is_field_v{ is_field<T>::value };
1958 template <
typename T>
1959 struct is_function_2 : std::is_base_of<
typename T::member_type,
member::
function>
1967 template <
typename T>
1975 template <
typename T>
1976 [[maybe_unused]]
static constexpr bool is_function_v{ is_function<T>::value };
1982 template <
typename T>
1991 template <
typename T>
1997 template <
typename T>
2005 template <
typename T>
2006 [[maybe_unused]]
static constexpr bool is_descriptor_v{ is_descriptor<T>::value };
2010 template <
typename T>
2017 template <
typename T>
2018 [[maybe_unused]]
static constexpr bool is_property_v{ is_property<T>::value };
2029 template <
typename Member>
2030 struct static_field_invoker
2032 static constexpr auto invoke() ->
decltype(*Member::pointer)
2034 return *Member::pointer;
2037 template <
typename U,
typename M = Member, std::enable_if_t<M::is_writable,
int> = 0>
2038 static constexpr auto invoke(U&& value) ->
decltype(*Member::pointer = std::forward<U>(value))
2040 return *Member::pointer = std::forward<U>(value);
2044 template <
typename Member>
2045 struct instance_field_invoker
2047 template <
typename T>
2048 static constexpr auto invoke(T&& target) ->
decltype(target.*(Member::pointer))
2050 return target.*(Member::pointer);
2053 template <
typename T,
typename U,
typename M = Member, std::enable_if_t<M::is_writable,
int> = 0>
2054 static constexpr auto invoke(T&& target, U&& value) ->
decltype(target.*(Member::pointer) = std::forward<U>(value))
2056 return target.*(Member::pointer) = std::forward<U>(value);
2060 template <
typename Member>
2061 static_field_invoker<Member> field_type_switch(std::true_type);
2063 template <
typename Member>
2064 instance_field_invoker<Member> field_type_switch(std::false_type);
2066 template <
typename Member>
2067 constexpr decltype(
nullptr) get_function_pointer(...)
2072 template <
typename Member>
2073 constexpr auto get_function_pointer(
int) ->
decltype(Member::pointer())
2075 return Member::pointer();
2078 template <
typename Member,
typename Pointer>
2079 constexpr decltype(
nullptr) resolve_function_pointer(...)
2084 template <
typename Member,
typename Pointer>
2085 constexpr auto resolve_function_pointer(
int) ->
decltype(Member::
template resolve<Pointer>())
2087 return Member::
template resolve<Pointer>();
2090 template <
typename T, size_t N>
2091 using make_descriptor = std::conditional_t<
refl::
trait::is_field_v<
refl::detail::member_info<T, N>>,
2092 field_descriptor<T, N>,
2093 std::conditional_t<
refl::
trait::is_function_v<
refl::detail::member_info<T, N>>,
2094 function_descriptor<T, N>,
2098 template <
typename T>
2099 type_list<> enumerate_members(std::index_sequence<>);
2101 template <
typename T, size_t... Idx>
2102 type_list<make_descriptor<T, Idx>...> enumerate_members(std::index_sequence<Idx...>);
2104 template <
typename T>
2105 struct declared_member_list
2107 static_assert(
refl::
trait::is_reflectable_v<T>,
"This type does not support reflection!");
2108 using type =
decltype(enumerate_members<T>(std::make_index_sequence<
refl::detail::type_info<T>::member_count>{}));
2111 template <
typename T>
2112 using attribute_types =
trait::as_type_list_t<std::remove_cv_t<
decltype(
refl::detail::type_info<T>::attributes)>>;
2117 template <
typename... TypeLists>
2118 struct flatten<
type_list<TypeLists...>> :
trait::concat<TypeLists...>
2122 template <
typename T,
typename Base>
2123 static constexpr void validate_base()
2125 static_assert(std::is_base_of_v<Base, T>,
"Base is not a base type of T!");
2128 template <
typename T,
typename... Bases>
2129 static constexpr void validate_bases(
type_list<Bases...>)
2131 util::ignore((validate_base<T, Bases>(), 0)...);
2134 template <
typename T>
2135 static constexpr auto get_declared_base_type_list()
2138 using base_types_type =
trait::remove_qualifiers_t<
decltype(
util::get_instance<
attr::
base_types>(
refl::detail::type_info<T>::attributes))>;
2139 validate_bases<T>(base_types_type::list);
2140 return typename base_types_type::list_type{};
2147 template <
typename T>
2148 struct declared_base_type_list
2150 using type =
decltype(get_declared_base_type_list<T>());
2153 template <
typename T>
2154 struct base_type_list;
2156 template <
typename T>
2157 static constexpr auto get_base_type_list()
2160 using declared_bases =
typename declared_base_type_list<T>::type;
2161 using rec_bases =
typename flatten<
trait::map_t<base_type_list, declared_bases>>::type;
2162 return trait::unique_t<
trait::concat_t<declared_bases, rec_bases>>{};
2169 template <
typename T>
2170 struct base_type_list
2172 using type =
decltype(get_base_type_list<T>());
2175 template <
typename T>
2176 struct member_list : flatten<
trait::map_t<declared_member_list,
trait::prepend_t<T,
typename base_type_list<T>::type>>>
2183 template <
typename T>
2184 using declared_member_list =
typename detail::declared_member_list<T>::type;
2187 template <
typename T>
2188 using member_list =
typename detail::member_list<T>::type;
2193 template <
typename T, size_t N>
2246 template <
typename T, size_t N>
2250 static_assert(
trait::is_field_v<member>);
2270 static constexpr bool is_static{ !std::is_member_object_pointer_v<
decltype(member::pointer)> };
2286 using invoker =
decltype(detail::field_type_switch<field_descriptor>(std::bool_constant<
is_static>{}));
2294 template <
decltype(
nullptr) =
nullptr>
2295 static constexpr decltype(
auto)
get()
noexcept
2297 return *member::pointer;
2304 template <
typename U>
2305 static constexpr decltype(
auto)
get(U&& target)
noexcept
2307 return target.*(member::pointer);
2314 template <
typename... Args>
2315 constexpr auto operator()(Args&&... args)
const noexcept ->
decltype(invoker::invoke(std::forward<Args>(args)...))
2317 return invoker::invoke(std::forward<Args>(args)...);
2325 template <
typename T, size_t N>
2329 static_assert(
trait::is_function_v<member>);
2339 template <
typename... Args>
2340 static constexpr auto invoke(Args&&... args) ->
decltype(member::invoke(std::declval<Args>()...))
2342 return member::invoke(std::forward<Args>(args)...);
2349 template <
typename... Args>
2350 using return_type =
decltype(member::invoke(std::declval<Args>()...));
2356 template <
typename... Args>
2357 constexpr auto operator()(Args&&... args)
const ->
decltype(invoke(std::declval<Args>()...))
2359 return invoke(std::forward<Args>(args)...);
2366 static constexpr auto pointer{ detail::get_function_pointer<member>(0) };
2379 template <
typename Pointer>
2382 return !std::is_same_v<
decltype(resolve<Pointer>()),
decltype(
nullptr)>;
2391 template <
typename Pointer>
2394 return detail::resolve_function_pointer<member, Pointer>(0);
2400 template <
typename T>
2401 class type_descriptor
2405 static_assert(
refl::
trait::is_reflectable_v<T>,
"This type does not support reflection!");
2407 typedef refl::detail::type_info<T> type_info;
2451 typedef detail::attribute_types<T> attribute_types;
2481 static constexpr const auto name{ type_info::name };
2506 template <
typename Descriptor>
2509 static_assert(
trait::is_descriptor_v<Descriptor>);
2523 template <
typename Descriptor>
2526 static_assert(
trait::is_descriptor_v<Descriptor>);
2527 return d.attributes;
2540 template <
typename Descriptor>
2543 static_assert(
trait::is_descriptor_v<Descriptor>);
2544 return trait::as_type_list_t<std::remove_cv_t<
decltype(d.attributes)>>{};
2563 template <
typename TypeDescriptor>
2566 static_assert(
trait::is_type_v<TypeDescriptor>);
2567 return t.declared_bases;
2586 template <
typename TypeDescriptor>
2589 static_assert(
trait::is_type_v<TypeDescriptor>);
2607 template <
typename TypeDescriptor>
2610 static_assert(
trait::is_type_v<TypeDescriptor>);
2611 return t.declared_members;
2628 template <
typename TypeDescriptor>
2631 static_assert(
trait::is_type_v<TypeDescriptor>);
2646 template <
typename MemberDescriptor>
2649 static_assert(
trait::is_member_v<MemberDescriptor>);
2650 return d.declarator;
2671 template <
typename MemberDescriptor>
2674 static_assert(
trait::is_member_v<MemberDescriptor>);
2695 template <
typename MemberDescriptor,
typename... Args>
2696 constexpr auto invoke(MemberDescriptor d, Args&&... args)
noexcept ->
decltype(d(std::forward<Args>(args)...))
2698 return d(std::forward<Args>(args)...);
2714 template <
typename FieldDescriptor>
2717 static_assert(
trait::is_field_v<FieldDescriptor>);
2734 template <
typename FieldDescriptor>
2737 static_assert(
trait::is_field_v<FieldDescriptor>);
2745 template <
typename FunctionDescriptor,
typename... Args>
2746 using result_type =
typename FunctionDescriptor::
template result_type<Args...>;
2762 template <
typename FunctionDescriptor>
2765 static_assert(
trait::is_function_v<FunctionDescriptor>);
2766 return d.is_resolved;
2784 template <
typename Pointer,
typename FunctionDescriptor>
2787 static_assert(
trait::is_function_v<FunctionDescriptor>);
2788 return d.
template can_resolve<Pointer>();
2805 template <
typename Pointer,
typename FunctionDescriptor>
2806 constexpr auto resolve(FunctionDescriptor d)
noexcept
2808 static_assert(
trait::is_function_v<FunctionDescriptor>);
2809 return d.
template resolve<Pointer>();
2823 template <
typename Descriptor>
2826 static_assert(
trait::is_descriptor_v<Descriptor>);
2827 return trait::is_field_v<Descriptor>;
2841 template <
typename Descriptor>
2844 static_assert(
trait::is_descriptor_v<Descriptor>);
2845 return trait::is_function_v<Descriptor>;
2858 template <
typename Descriptor>
2861 static_assert(
trait::is_descriptor_v<Descriptor>);
2862 return trait::is_type_v<Descriptor>;
2873 template <
typename A,
typename Descriptor>
2876 static_assert(
trait::is_descriptor_v<Descriptor>);
2877 return trait::contains_base_v<A,
typename Descriptor::attribute_types>;
2888 template <
template<
typename...>
typename A,
typename Descriptor>
2889 constexpr bool has_attribute(Descriptor)
noexcept
2891 static_assert(
trait::is_descriptor_v<Descriptor>);
2892 return trait::contains_instance_v<A,
typename Descriptor::attribute_types>;
2903 template <
typename A,
typename Descriptor>
2906 static_assert(
trait::is_descriptor_v<Descriptor>);
2907 return util::get<A>(d.attributes);
2918 template <
template<
typename...>
typename A,
typename Descriptor>
2921 static_assert(
trait::is_descriptor_v<Descriptor>);
2922 return util::get_instance<A>(d.attributes);
2936 template <
typename MemberDescriptor>
2939 static_assert(
trait::is_member_v<MemberDescriptor>);
2954 template <
typename FunctionDescriptor>
2957 static_assert(
trait::is_function_v<FunctionDescriptor>);
2965 template <
typename T>
2979 template <
typename MemberDescriptor>
2982 static_assert(
trait::is_member_v<MemberDescriptor>);
2983 if constexpr (
trait::is_property_v<MemberDescriptor>) {
2984 if constexpr (std::is_invocable_v<MemberDescriptor,
const typename MemberDescriptor::declaring_type&>) {
2985 using return_type =
typename MemberDescriptor::
template return_type<
const typename MemberDescriptor::declaring_type&>;
2986 return !std::is_void_v<return_type>;
2993 return trait::is_field_v<MemberDescriptor>;
3007 template <
typename MemberDescriptor>
3010 static_assert(
trait::is_member_v<MemberDescriptor>);
3011 if constexpr (
trait::is_property_v<MemberDescriptor>) {
3012 return std::is_invocable_v<MemberDescriptor,
typename MemberDescriptor::declaring_type&, detail::placeholder>;
3014 else if constexpr (
trait::is_field_v<MemberDescriptor>) {
3015 return !std::is_const_v<
typename trait::remove_qualifiers_t<MemberDescriptor>::value_type>;
3024 template <
typename T>
3025 struct get_type_descriptor
3027 typedef type_descriptor<T> type;
3043 template <
typename TypeDescriptor>
3044 [[deprecated]]
constexpr auto has_bases(TypeDescriptor t)
noexcept
3046 static_assert(
trait::is_type_v<TypeDescriptor>);
3063 template <
typename TypeDescriptor>
3064 [[deprecated]]
constexpr auto get_bases(TypeDescriptor t)
noexcept
3066 static_assert(
trait::is_type_v<TypeDescriptor>);
3067 static_assert(has_bases(t),
"Target type does not have a bases<A, B, ...> attribute.");
3070 using base_types =
typename decltype(bases)::list_type;
3071 return trait::map_t<detail::get_type_descriptor, base_types>{};
3081 template <
typename TypeDescriptor>
3084 static_assert(
trait::is_type_v<TypeDescriptor>);
3085 constexpr size_t template_start = t.name.find(
'<');
3086 constexpr size_t scope_last = t.name.rfind(
':', template_start);
3091 return t.name.
template substr<scope_last + 1, template_start - scope_last - 1>();
3103 template <
typename MemberDescriptor>
3106 static_assert(
trait::is_member_v<MemberDescriptor>);
3107 return d.declarator.name +
"::" + d.name;
3117 template <
typename MemberDescriptor>
3120 static_assert(
trait::is_member_v<MemberDescriptor>);
3121 static const std::string name(get_debug_name_const(d).str());
3122 return name.c_str();
3127 constexpr bool is_upper(
char ch)
3129 return ch >=
'A' && ch <=
'Z';
3132 constexpr char to_upper(
char ch)
3134 return ch >=
'a' && ch <=
'z'
3135 ?
char(ch + (
'A' -
'a'))
3139 constexpr char to_lower(
char ch)
3141 return ch >=
'A' && ch <=
'Z'
3142 ?
char(ch + (
'a' -
'A'))
3146 template <
typename T,
bool PreferUpper>
3147 constexpr auto normalize_bare_accessor_name()
3149 constexpr auto str = T::name.
template substr<3>();
3150 if constexpr (str.data[0] ==
'_') {
3151 return str.
template substr<1>();
3153 else if constexpr (!PreferUpper && str.data[0] >=
'A' && str.data[0] <=
'Z') {
3154 return make_const_string(to_lower(str.data[0])) + str.
template substr<1>();
3156 else if constexpr (PreferUpper) {
3157 return make_const_string(to_upper(str.data[0])) + str.
template substr<1>();
3164 template <
typename T>
3165 constexpr auto normalize_accessor_name(
const T)
3168 if constexpr (t.name.size > 3) {
3169 constexpr auto prefix = t.name.
template substr<0, 3>();
3170 constexpr bool cont_snake_or_camel = (t.name.size > 4 && t.name.data[3] ==
'_' && !is_upper(t.name.data[4])) || is_upper(t.name.data[3]);
3171 constexpr bool cont_pascal = is_upper(t.name.data[3]);
3173 if constexpr ((is_readable(T{}) && ((prefix ==
"Get" && cont_pascal) || (prefix ==
"get" && cont_snake_or_camel)))
3174 || (is_writable(T{}) && ((prefix ==
"Set" && cont_pascal) || (prefix ==
"set" && cont_snake_or_camel)))) {
3175 constexpr bool prefer_upper = is_upper(prefix.data[0]);
3176 return normalize_bare_accessor_name<T, prefer_upper>();
3187 template <
typename T>
3188 std::string get_display_name(
const T t)
noexcept
3190 if constexpr (
trait::is_property_v<T>) {
3191 auto&& friendly_name =
util::get<
attr::
property>(t.attributes).friendly_name;
3192 return friendly_name ? *friendly_name : detail::normalize_accessor_name(t).str();
3195 return t.name.str();
3225 template <
typename Descriptor>
3228 static_assert(
trait::is_descriptor_v<Descriptor>);
3229 static const std::string name(detail::get_display_name(d));
3230 return name.c_str();
3242 template <
typename T>
3245 return trait::is_reflectable_v<T>;
3249 template <
typename T>
3252 return trait::is_reflectable_v<T>;
3256 template<
typename T>
3263 template<
typename T>
3264 constexpr type_descriptor<T>
reflect(
const T&)
noexcept
3269 #ifndef REFL_DETAIL_FORCE_EBO
3271 #define REFL_DETAIL_FORCE_EBO __declspec(empty_bases)
3273 #define REFL_DETAIL_FORCE_EBO
3282 template <
typename Derived,
typename Target>
3287 template <
typename T>
3288 struct get_member_info;
3290 template <
typename T, size_t N>
3291 struct get_member_info<
refl::function_descriptor<T, N>>
3293 using type =
refl::detail::member_info<T, N>;
3296 template <
typename T, size_t N>
3297 struct get_member_info<
refl::field_descriptor<T, N>>
3299 using type =
refl::detail::member_info<T, N>;
3302 template <
typename T,
typename U>
3303 constexpr T& static_ref_cast(U& value)
noexcept
3305 return static_cast<T&>(value);
3308 template <
typename T,
typename U>
3309 constexpr const T& static_ref_cast(
const U& value)
noexcept
3311 return static_cast<
const T&>(value);
3314 template <
typename... Results>
3320 template <
typename Member,
typename... Members,
typename... Results>
3321 constexpr auto get_members_skip_shadowed(
type_list<Member, Members...>,
type_list<Results...>)
3323 if constexpr ((... || (Results::name == Member::name))) {
3327 return get_members_skip_shadowed(
type_list<Members...>{},
type_list<Results..., Member>{});
3331 template <
typename T>
3332 using members_skip_shadowed =
decltype(get_members_skip_shadowed(member_list<T>{},
type_list<>{}));
3335 template <
typename Derived,
typename Func>
3336 struct REFL_DETAIL_FORCE_EBO function_proxy :
public get_member_info<Func>::type::
template remap<function_proxy<Derived, Func>>
3342 template <
typename Self,
typename... Args>
3343 static constexpr decltype(
auto) invoke_impl(Self&& self, Args&& ... args)
3345 return Derived::
template invoke_impl<Func>(static_ref_cast<Derived>(self), std::forward<Args>(args)...);
3349 template <
typename,
typename>
3353 template <
typename Derived,
typename... Members>
3359 template <
typename Derived,
typename Field>
3360 struct REFL_DETAIL_FORCE_EBO field_proxy :
public get_member_info<Field>::type::
template remap<field_proxy<Derived, Field>>
3366 template <
typename Self,
typename... Args>
3367 static constexpr decltype(
auto) invoke_impl(Self&& self, Args&& ... args)
3369 return Derived::
template invoke_impl<Field>(static_ref_cast<Derived>(self), std::forward<Args>(args)...);
3374 template <
typename,
typename>
3378 template <
typename Derived,
typename... Members>
3383 template <
typename T>
3386 template <
typename T>
3409 template <
typename Derived,
typename Target>
3411 :
public detail::function_proxies<
proxy<Derived, Target>, detail::functions<Target>>
3412 ,
public detail::field_proxies<
proxy<Derived, Target>, detail::fields<Target>>
3415 sizeof(detail::function_proxies<
proxy<Derived, Target>, detail::functions<Target>>) == 1 &&
3416 sizeof(detail::field_proxies<
proxy<Derived, Target>, detail::fields<Target>>) == 1,
3417 "Multiple inheritance EBO did not kick in! "
3418 "You could try defining the REFL_DETAIL_FORCE_EBO macro appropriately to enable it on the required types. "
3419 "Default for MSC is `__declspec(empty_bases)`.");
3422 trait::is_reflectable_v<Target>,
3423 "Target type must be reflectable!");
3431 template <
typename P,
typename F>
3432 friend struct detail::function_proxy;
3434 template <
typename P,
typename F>
3435 friend struct detail::field_proxy;
3438 template <
typename Member,
typename Self,
typename... Args>
3439 static constexpr decltype(
auto) invoke_impl(Self&& self, Args&& ... args)
3441 return Derived::
template invoke_impl<Member>(detail::static_ref_cast<Derived>(self), std::forward<Args>(args)...);
3453 template <
typename T>
3457 template <
typename Derived,
typename Target>
3458 static std::true_type test(
runtime::
proxy<Derived, Target>*);
3459 static std::false_type test(...);
3461 static constexpr bool value{ !std::is_reference_v<T> &&
decltype(test(std::declval<remove_qualifiers_t<T>*>()))::value };
3464 template <
typename T>
3465 [[maybe_unused]]
static constexpr bool is_proxy_v{ is_proxy<T>::value };
3470 template <
typename CharT,
typename T>
3471 void debug(std::basic_ostream<CharT>& os,
const T& value,
bool compact =
false);
3475 template <
typename CharT,
typename T,
typename =
decltype(std::declval<std::basic_ostream<CharT>&>() << std::declval<T>())>
3476 std::true_type is_ostream_printable_test(
int);
3478 template <
typename CharT,
typename T>
3479 std::false_type is_ostream_printable_test(...);
3481 template <
typename CharT,
typename T>
3482 constexpr bool is_ostream_printable_v{
decltype(is_ostream_printable_test<CharT, T>(0))::value };
3484 int next_depth(
int depth)
3486 return depth == -1 || depth > 8
3491 template <
typename CharT>
3492 void indent(std::basic_ostream<CharT>& os,
int depth)
3494 for (
int i = 0; i < depth; i++) {
3499 template <
typename CharT,
typename T>
3500 void debug_impl(std::basic_ostream<CharT>& os,
const T& value, [[maybe_unused]]
int depth);
3502 template <
typename CharT,
typename T>
3503 void debug_detailed(std::basic_ostream<CharT>& os,
const T& value,
int depth)
3505 using type_descriptor = type_descriptor<T>;
3506 bool compact = depth == -1;
3508 os << type_descriptor::name <<
" { ";
3509 if (!compact) os <<
'\n';
3511 constexpr auto readable_members = filter(type_descriptor::members, [](
auto member) {
return is_readable(member); });
3512 for_each(readable_members, [&](
auto member, [[maybe_unused]]
auto index) {
3513 int new_depth = next_depth(depth);
3515 indent(os, new_depth);
3516 os << get_display_name(member) <<
" = ";
3518 if constexpr (
util::contains_instance<
attr::
debug>(member.attributes)) {
3520 auto debug_attr =
util::get_instance<
attr::
debug>(member.attributes);
3521 debug_attr.write(os, value);
3524 debug_impl(os, member(value), new_depth);
3527 if (!compact || index + 1 != readable_members.size) {
3536 if (compact) os <<
' ';
3541 template <
typename CharT,
typename T>
3542 void debug_reflectable(std::basic_ostream<CharT>& os,
const T& value, [[maybe_unused]]
int depth)
3544 using type_descriptor = type_descriptor<T>;
3545 if constexpr (
trait::contains_instance_v<
attr::
debug,
typename type_descriptor::attribute_types>) {
3547 auto debug_attr =
util::get_instance<
attr::
debug>(type_descriptor::attributes);
3548 debug_attr.write(os, value);
3550 else if constexpr (detail::is_ostream_printable_v<CharT, T>) {
3555 debug_detailed(os, value, depth);
3559 template <
typename CharT,
typename T>
3560 void debug_container(std::basic_ostream<CharT>& os,
const T& value,
int depth)
3562 bool compact = depth == -1;
3565 auto end = value.end();
3566 for (
auto it = value.begin(); it != end; ++it)
3568 if (!compact) os <<
'\n';
3569 int new_depth = next_depth(depth);
3570 indent(os, new_depth);
3572 debug_impl(os, *it, new_depth);
3573 if (std::next(it, 1) != end) {
3576 else if (!compact) {
3585 template <
typename CharT,
typename T>
3586 void debug_impl(std::basic_ostream<CharT>& os,
const T& value, [[maybe_unused]]
int depth)
3588 using no_pointer_t = std::remove_pointer_t<T>;
3590 if constexpr (std::is_same_v<
bool, T>) {
3591 os << (value ?
"true" :
"false");
3593 else if constexpr (std::is_pointer_v<T> && !std::is_void_v<no_pointer_t> &&
trait::is_reflectable_v<no_pointer_t>) {
3594 if (value ==
nullptr) {
3599 debug_impl(os, *value, -1);
3602 else if constexpr (
trait::is_reflectable_v<T>) {
3603 debug_reflectable(os, value, depth);
3605 else if constexpr (detail::is_ostream_printable_v<CharT, T>) {
3608 else if constexpr (
trait::is_container_v<T>) {
3609 debug_container(os, value, depth);
3612 os <<
"(not printable)";
3624 template <
typename CharT,
typename T>
3627 static_assert(
trait::is_reflectable_v<T> ||
trait::is_container_v<T> || detail::is_ostream_printable_v<CharT, T>,
3628 "Type is not reflectable, not a container of reflectable types and does not support operator<<(std::ostream&, T)!");
3630 detail::debug_impl(os, value, compact ? -1 : 0);
3636 template <
typename CharT,
typename... Ts>
3637 void debug_all(std::basic_ostream<CharT>& os,
const Ts&... values)
3639 refl::
runtime::debug(os, std::forward_as_tuple(
static_cast<
const Ts&>(values)...),
true);
3647 template <
typename CharT =
char,
typename T>
3648 std::basic_string<CharT>
debug_str(
const T& value,
bool compact =
false)
3650 std::basic_stringstream<CharT> ss;
3651 debug(ss, value, compact);
3658 template <
typename CharT =
char,
typename... Ts>
3661 return refl::
runtime::debug_str(std::forward_as_tuple(
static_cast<
const Ts&>(values)...),
true);
3672 template <
typename U,
typename T,
typename... Args>
3673 U
invoke(T&& target,
const char* name, Args&&... args)
3675 using type = std::remove_reference_t<T>;
3676 static_assert(
refl::
trait::is_reflectable_v<type>,
"Unsupported type!");
3677 typedef type_descriptor<type> type_descriptor;
3679 std::optional<U> result;
3681 bool found{
false };
3682 for_each(type_descriptor::members, [&](
auto member) {
3683 using member_t =
decltype(member);
3686 if constexpr (std::is_invocable_r_v<U,
decltype(member), T, Args...>) {
3687 if constexpr (
trait::is_member_v<member_t>) {
3688 if (std::strcmp(member.name.c_str(), name) == 0) {
3689 result.emplace(member(target, std::forward<Args>(args)...));
3697 return std::move(*result);
3700 throw std::runtime_error(std::string(
"The member ")
3701 + type_descriptor::name.str() +
"::" + name
3702 +
" is not compatible with the provided parameters or return type, is not reflected or does not exist!");
3710 namespace refl::detail
3712 constexpr bool validate_attr_unique(
type_list<>)
noexcept
3718 template <
typename T,
typename... Ts>
3719 constexpr bool validate_attr_unique(
type_list<T, Ts...>)
noexcept
3721 constexpr bool cond = (... && (!std::is_same_v<T, Ts> && validate_attr_unique(
type_list<Ts>{})));
3722 static_assert(cond,
"Some of the attributes provided have duplicate types!");
3726 template <
typename Req,
typename Attr>
3727 constexpr bool validate_attr_usage()
noexcept
3729 return std::is_base_of_v<Req, Attr>;
3737 template <
typename Req,
typename... Args>
3738 constexpr auto make_attributes(Args&&... args)
noexcept
3740 constexpr bool check_unique = validate_attr_unique(
type_list<Args...>{});
3741 static_assert(check_unique,
"Some of the supplied attributes cannot be used on this declaration!");
3743 constexpr bool check_usage = (... && validate_attr_usage<Req,
trait::remove_qualifiers_t<Args>>());
3744 static_assert(check_usage,
"Some of the supplied attributes cannot be used on this declaration!");
3746 return std::make_tuple(std::forward<Args>(args)...);
3749 template <
typename T,
typename...>
3759 template <
typename T,
typename... Ts>
3760 using head_t =
typename head<T, Ts...>::type;
3762 template <
typename T,
typename U>
3763 struct transfer_const
3765 using type = std::conditional_t<std::is_const_v<T>, std::add_const_t<U>, U>;
3768 template <
typename T,
typename U>
3769 struct transfer_volatile
3771 using type = std::conditional_t<std::is_volatile_v<T>, std::add_volatile_t<U>, U>;
3774 template <
typename T,
typename U>
3775 struct transfer_cv : transfer_const<T,
typename transfer_volatile<T, U>::type>
3779 template <
typename T,
typename U>
3780 struct transfer_lvalue_ref
3782 using type = std::conditional_t<std::is_lvalue_reference_v<T>, std::add_lvalue_reference_t<U>, U>;
3785 template <
typename T,
typename U>
3786 struct transfer_rvalue_ref
3788 using type = std::conditional_t<std::is_rvalue_reference_v<T>, std::add_rvalue_reference_t<U>, U>;
3791 template <
typename T,
typename U>
3792 struct transfer_ref : transfer_rvalue_ref<T,
typename transfer_lvalue_ref<T, U>::type>
3796 template <
typename T,
typename U>
3797 struct transfer_cvref : transfer_ref<T,
typename transfer_cv<std::remove_reference_t<T>, U>::type>
3801 template <
typename T,
typename U>
3802 constexpr auto forward_cast(std::remove_reference_t<T>& t) ->
decltype(
static_cast<
typename transfer_cvref<T, U>::type&&>(t))
3804 return static_cast<
typename transfer_cvref<T, U>::type&&>(t);
3807 template <
typename T,
typename U>
3808 constexpr auto forward_cast(std::remove_reference_t<T>&& t) ->
decltype(
static_cast<
typename transfer_cvref<T, U>::type&&>(t))
3810 static_assert(!std::is_lvalue_reference_v<T>,
"template argument substituting T is an lvalue reference type");
3811 return static_cast<
typename transfer_cvref<T, U>::type&&>(t);
3814 template <
typename T>
3815 constexpr auto get_type_name()
3817 if constexpr (
trait::is_reflectable_v<T>) {
3818 return type_descriptor<T>::name;
3831 #define REFL_DETAIL_STR_IMPL(...) #__VA_ARGS__
3835 #define REFL_DETAIL_GROUP(...) __VA_ARGS__
3842 #define REFL_DETAIL_ATTRIBUTES(DeclType, ...)
3843 static constexpr auto attributes{ ::refl::detail::make_attributes<::refl::attr::usage:: DeclType>(__VA_ARGS__) };
3848 #define REFL_DETAIL_TYPE_BODY(TypeName, ...)
3852 static constexpr size_t member_index_offset = __COUNTER__ + 1
;
3853 template <size_t, typename = void>
3867 #define REFL_TYPE(TypeName, ...)
3868 namespace refl_impl::metadata { template<> struct type_info__<TypeName> {
3884 #define REFL_TEMPLATE(TemplateDeclaration, TypeName, ...)
3898 static constexpr size_t member_count{ __COUNTER__ - member_index_offset };
3901 #define REFL_DETAIL_MEMBER_HEADER template<typename Unused__> struct member<__COUNTER__ - member_index_offset, Unused__>
3903 #define REFL_DETAIL_MEMBER_COMMON(MemberType_, MemberName_, ...)
3904 typedef ::refl::member::MemberType_ member_type;
3905 static constexpr auto name{ ::refl::util::make_const_string(REFL_DETAIL_STR(MemberName_)) };
3915 #define REFL_DETAIL_MEMBER_PROXY(MemberName_)
3916 template <typename Proxy> struct remap {
3917 template <typename... Args> decltype(auto) MemberName_(Args&&... args) {
3918 return Proxy::invoke_impl(static_cast<Proxy&>(*this), ::std::forward<Args>(args)...);
3920 template <typename... Args> decltype(auto) MemberName_(Args&&... args) const {
3921 return Proxy::invoke_impl(static_cast<const Proxy&>(*this), ::std::forward<Args>(args)...);
3928 #define REFL_FIELD(FieldName_, ...)
3929 REFL_DETAIL_MEMBER_HEADER
{
3930 REFL_DETAIL_MEMBER_COMMON
(field, FieldName_, __VA_ARGS__)
3932 typedef decltype(type::FieldName_) value_type;
3933 static constexpr auto pointer{ &type::FieldName_ };
3934 REFL_DETAIL_MEMBER_PROXY
(FieldName_);
3940 #define REFL_FUNC(FunctionName_, ...)
3941 REFL_DETAIL_MEMBER_HEADER
{
3942 REFL_DETAIL_MEMBER_COMMON
(function, FunctionName_, __VA_ARGS__)
3944 template<typename Self, typename... Args> static constexpr auto invoke(Self&& self, Args&&... args) -> decltype(::refl::detail::forward_cast<Self, type>(self).FunctionName_(::std::forward<Args>(args)...)) {
3945 return ::refl::detail::forward_cast<Self, type>(self).FunctionName_(::std::forward<Args>(args)...);
3947 template<typename... Args> static constexpr auto invoke(Args&&... args) -> decltype(::refl::detail::head_t<type, Args...>::FunctionName_(::std::declval<Args>()...)) {
3948 return ::refl::detail::head_t<type, Args...>::FunctionName_(::std::forward<Args>(args)...);
3950 template <typename Dummy = void>
3951 static constexpr auto pointer() -> decltype(&::refl::detail::head_t<type, Dummy>::FunctionName_) { return &::refl::detail::head_t<type, Dummy>::FunctionName_; }
3952 template <typename Pointer>
3953 static constexpr auto resolve() -> ::std::decay_t<decltype(Pointer(&type::FunctionName_))> { return Pointer(&type::FunctionName_); }
3954 REFL_DETAIL_MEMBER_PROXY
(FunctionName_);
3961 #define REFL_DETAIL_PRIMITIVE(TypeName)
3966 REFL_DETAIL_PRIMITIVE(
char);
3967 REFL_DETAIL_PRIMITIVE(
wchar_t);
3968 REFL_DETAIL_PRIMITIVE(
char16_t);
3969 REFL_DETAIL_PRIMITIVE(
char32_t);
3970 #ifdef __cpp_lib_char8_t
3971 REFL_DETAIL_PRIMITIVE(char8_t);
3975 REFL_DETAIL_PRIMITIVE(
bool);
3976 REFL_DETAIL_PRIMITIVE(
signed char);
3977 REFL_DETAIL_PRIMITIVE(
unsigned char);
3978 REFL_DETAIL_PRIMITIVE(
signed short);
3979 REFL_DETAIL_PRIMITIVE(
unsigned short);
3980 REFL_DETAIL_PRIMITIVE(
signed int);
3981 REFL_DETAIL_PRIMITIVE(
unsigned int);
3982 REFL_DETAIL_PRIMITIVE(
signed long);
3983 REFL_DETAIL_PRIMITIVE(
unsigned long);
3984 REFL_DETAIL_PRIMITIVE(
signed long long);
3985 REFL_DETAIL_PRIMITIVE(
unsigned long long);
3988 REFL_DETAIL_PRIMITIVE(
float);
3989 REFL_DETAIL_PRIMITIVE(
double);
3990 REFL_DETAIL_PRIMITIVE(
long double);
3993 REFL_DETAIL_PRIMITIVE(
decltype(nullptr));
3999 #undef REFL_DETAIL_PRIMITIVE
4001 #define REFL_DETAIL_POINTER(Ptr)
4002 template<typename T>
4003 struct type_info__<T Ptr> {
4007 static constexpr auto name{ ::refl::detail::get_type_name<T>() + ::refl::util::make_const_string(#Ptr) };
4008 static constexpr ::std::tuple<> attributes{ };
4009 static constexpr size_t member_count{ 0
};
4016 REFL_DETAIL_POINTER(*);
4017 REFL_DETAIL_POINTER(&);
4018 REFL_DETAIL_POINTER(&&);
4022 #undef REFL_DETAIL_POINTER
4024 namespace refl::detail
4026 template <
typename CharT>
4027 std::basic_string<CharT> convert(
const std::string& str)
4029 return std::basic_string<CharT>(str.begin(), str.end());
4032 #ifdef __cpp_lib_string_view
4033 struct write_basic_string_view
4035 template <
typename CharT,
typename Traits>
4036 void operator()(std::basic_ostream<CharT>& os, std::basic_string_view<CharT, Traits> str)
const
4040 os << std::quoted(str.data());
4043 os << std::quoted(std::basic_string<CharT, Traits>(str.begin(), str.end()));
4049 struct write_basic_string
4051 template <
typename CharT,
typename Traits,
typename Allocator>
4052 void operator()(std::basic_ostream<CharT>& os,
const std::basic_string<CharT, Traits, Allocator>& str)
const
4054 os << std::quoted(str);
4058 struct write_exception
4060 template <
typename CharT>
4061 void operator()(std::basic_ostream<CharT>& os,
const std::exception& e)
const
4063 os << convert<CharT>(
"Exception");
4064 #ifdef REFL_RTTI_ENABLED
4065 os << convert<CharT>(
" (") << convert<CharT>(
typeid(e).name()) << convert<CharT>(
")");
4067 os << convert<CharT>(
": `") << e.what() << convert<CharT>(
"`");
4073 template <
typename CharT,
typename Tuple, size_t... Idx>
4074 void write(std::basic_ostream<CharT>& os, Tuple&& t, std::index_sequence<Idx...>)
const
4077 for_each(
type_list<std::integral_constant<size_t, Idx>...>{}, [&](
auto idx_c) {
4078 using idx_t =
decltype(idx_c);
4079 runtime::debug(os, std::get<idx_t::value>(t));
4080 if constexpr (
sizeof...(Idx) - 1 != idx_t::value) {
4081 os << convert<CharT>(
", ");
4087 template <
typename CharT,
typename... Ts>
4088 void operator()(std::basic_ostream<CharT>& os,
const std::tuple<Ts...>& t)
const
4090 write(os, t, std::make_index_sequence<
sizeof...(Ts)>{});
4096 template <
typename CharT,
typename K,
typename V>
4097 void operator()(std::basic_ostream<CharT>& os,
const std::pair<K, V>& t)
const
4101 os << convert<CharT>(
", ");
4107 struct write_unique_ptr
4109 template <
typename CharT,
typename T,
typename D>
4110 void operator()(std::basic_ostream<CharT>& os,
const std::unique_ptr<T, D>& t)
const
4112 runtime::debug(os, t.get(),
true);
4116 struct write_shared_ptr
4118 template <
typename CharT,
typename T>
4119 void operator()(std::basic_ostream<CharT>& os,
const std::shared_ptr<T>& t)
const
4121 runtime::debug(os, t.get(),
true);
4125 struct write_weak_ptr
4127 template <
typename CharT,
typename T>
4128 void operator()(std::basic_ostream<CharT>& os,
const std::weak_ptr<T>& t)
const
4130 runtime::debug(os, t.lock().get(),
true);
4138 #ifndef REFL_NO_STD_SUPPORT
4145 (
typename Elem,
typename Traits,
typename Alloc),
4152 #ifdef __cpp_lib_string_view
4155 (
typename Elem,
typename Traits),
4171 (
typename T,
typename D),
4183 (
typename K,
typename V),
4190 #ifndef REFL_NO_AUTO_MACRO
4192 #define REFL_DETAIL_EXPAND(x) x
4193 #define REFL_DETAIL_FOR_EACH_0(...)
4194 #define REFL_DETAIL_FOR_EACH_1(what, x, ...) what(x)
4195 #define REFL_DETAIL_FOR_EACH_2(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_1
(what, __VA_ARGS__))
4196 #define REFL_DETAIL_FOR_EACH_3(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_2
(what, __VA_ARGS__))
4197 #define REFL_DETAIL_FOR_EACH_4(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_3
(what, __VA_ARGS__))
4198 #define REFL_DETAIL_FOR_EACH_5(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_4
(what, __VA_ARGS__))
4199 #define REFL_DETAIL_FOR_EACH_6(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_5
(what, __VA_ARGS__))
4200 #define REFL_DETAIL_FOR_EACH_7(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_6
(what, __VA_ARGS__))
4201 #define REFL_DETAIL_FOR_EACH_8(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_7
(what, __VA_ARGS__))
4202 #define REFL_DETAIL_FOR_EACH_9(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_8
(what, __VA_ARGS__))
4203 #define REFL_DETAIL_FOR_EACH_10(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_9
(what, __VA_ARGS__))
4204 #define REFL_DETAIL_FOR_EACH_11(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_10
(what, __VA_ARGS__))
4205 #define REFL_DETAIL_FOR_EACH_12(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_11
(what, __VA_ARGS__))
4206 #define REFL_DETAIL_FOR_EACH_13(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_12
(what, __VA_ARGS__))
4207 #define REFL_DETAIL_FOR_EACH_14(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_13
(what, __VA_ARGS__))
4208 #define REFL_DETAIL_FOR_EACH_15(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_14
(what, __VA_ARGS__))
4209 #define REFL_DETAIL_FOR_EACH_16(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_15
(what, __VA_ARGS__))
4210 #define REFL_DETAIL_FOR_EACH_17(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_16
(what, __VA_ARGS__))
4211 #define REFL_DETAIL_FOR_EACH_18(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_17
(what, __VA_ARGS__))
4212 #define REFL_DETAIL_FOR_EACH_19(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_18
(what, __VA_ARGS__))
4213 #define REFL_DETAIL_FOR_EACH_20(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_19
(what, __VA_ARGS__))
4214 #define REFL_DETAIL_FOR_EACH_21(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_20
(what, __VA_ARGS__))
4215 #define REFL_DETAIL_FOR_EACH_22(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_21
(what, __VA_ARGS__))
4216 #define REFL_DETAIL_FOR_EACH_23(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_22
(what, __VA_ARGS__))
4217 #define REFL_DETAIL_FOR_EACH_24(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_23
(what, __VA_ARGS__))
4218 #define REFL_DETAIL_FOR_EACH_25(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_24
(what, __VA_ARGS__))
4219 #define REFL_DETAIL_FOR_EACH_26(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_25
(what, __VA_ARGS__))
4220 #define REFL_DETAIL_FOR_EACH_27(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_26
(what, __VA_ARGS__))
4221 #define REFL_DETAIL_FOR_EACH_28(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_27
(what, __VA_ARGS__))
4222 #define REFL_DETAIL_FOR_EACH_29(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_28
(what, __VA_ARGS__))
4223 #define REFL_DETAIL_FOR_EACH_30(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_29
(what, __VA_ARGS__))
4224 #define REFL_DETAIL_FOR_EACH_31(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_30
(what, __VA_ARGS__))
4225 #define REFL_DETAIL_FOR_EACH_32(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_31
(what, __VA_ARGS__))
4226 #define REFL_DETAIL_FOR_EACH_33(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_32
(what, __VA_ARGS__))
4227 #define REFL_DETAIL_FOR_EACH_34(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_33
(what, __VA_ARGS__))
4228 #define REFL_DETAIL_FOR_EACH_35(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_34
(what, __VA_ARGS__))
4229 #define REFL_DETAIL_FOR_EACH_36(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_35
(what, __VA_ARGS__))
4230 #define REFL_DETAIL_FOR_EACH_37(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_36
(what, __VA_ARGS__))
4231 #define REFL_DETAIL_FOR_EACH_38(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_37
(what, __VA_ARGS__))
4232 #define REFL_DETAIL_FOR_EACH_39(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_38
(what, __VA_ARGS__))
4233 #define REFL_DETAIL_FOR_EACH_40(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_39
(what, __VA_ARGS__))
4234 #define REFL_DETAIL_FOR_EACH_41(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_40
(what, __VA_ARGS__))
4235 #define REFL_DETAIL_FOR_EACH_42(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_41
(what, __VA_ARGS__))
4236 #define REFL_DETAIL_FOR_EACH_43(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_42
(what, __VA_ARGS__))
4237 #define REFL_DETAIL_FOR_EACH_44(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_43
(what, __VA_ARGS__))
4238 #define REFL_DETAIL_FOR_EACH_45(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_44
(what, __VA_ARGS__))
4239 #define REFL_DETAIL_FOR_EACH_46(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_45
(what, __VA_ARGS__))
4240 #define REFL_DETAIL_FOR_EACH_47(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_46
(what, __VA_ARGS__))
4241 #define REFL_DETAIL_FOR_EACH_48(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_47
(what, __VA_ARGS__))
4242 #define REFL_DETAIL_FOR_EACH_49(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_48
(what, __VA_ARGS__))
4243 #define REFL_DETAIL_FOR_EACH_50(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_49
(what, __VA_ARGS__))
4244 #define REFL_DETAIL_FOR_EACH_51(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_50
(what, __VA_ARGS__))
4245 #define REFL_DETAIL_FOR_EACH_52(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_51
(what, __VA_ARGS__))
4246 #define REFL_DETAIL_FOR_EACH_53(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_52
(what, __VA_ARGS__))
4247 #define REFL_DETAIL_FOR_EACH_54(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_53
(what, __VA_ARGS__))
4248 #define REFL_DETAIL_FOR_EACH_55(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_54
(what, __VA_ARGS__))
4249 #define REFL_DETAIL_FOR_EACH_56(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_55
(what, __VA_ARGS__))
4250 #define REFL_DETAIL_FOR_EACH_57(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_56
(what, __VA_ARGS__))
4251 #define REFL_DETAIL_FOR_EACH_58(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_57
(what, __VA_ARGS__))
4252 #define REFL_DETAIL_FOR_EACH_59(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_58
(what, __VA_ARGS__))
4253 #define REFL_DETAIL_FOR_EACH_60(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_59
(what, __VA_ARGS__))
4254 #define REFL_DETAIL_FOR_EACH_61(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_60
(what, __VA_ARGS__))
4255 #define REFL_DETAIL_FOR_EACH_62(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_61
(what, __VA_ARGS__))
4256 #define REFL_DETAIL_FOR_EACH_63(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_62
(what, __VA_ARGS__))
4257 #define REFL_DETAIL_FOR_EACH_64(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_63
(what, __VA_ARGS__))
4258 #define REFL_DETAIL_FOR_EACH_65(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_64
(what, __VA_ARGS__))
4259 #define REFL_DETAIL_FOR_EACH_66(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_65
(what, __VA_ARGS__))
4260 #define REFL_DETAIL_FOR_EACH_67(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_66
(what, __VA_ARGS__))
4261 #define REFL_DETAIL_FOR_EACH_68(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_67
(what, __VA_ARGS__))
4262 #define REFL_DETAIL_FOR_EACH_69(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_68
(what, __VA_ARGS__))
4263 #define REFL_DETAIL_FOR_EACH_70(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_69
(what, __VA_ARGS__))
4264 #define REFL_DETAIL_FOR_EACH_71(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_70
(what, __VA_ARGS__))
4265 #define REFL_DETAIL_FOR_EACH_72(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_71
(what, __VA_ARGS__))
4266 #define REFL_DETAIL_FOR_EACH_73(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_72
(what, __VA_ARGS__))
4267 #define REFL_DETAIL_FOR_EACH_74(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_73
(what, __VA_ARGS__))
4268 #define REFL_DETAIL_FOR_EACH_75(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_74
(what, __VA_ARGS__))
4269 #define REFL_DETAIL_FOR_EACH_76(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_75
(what, __VA_ARGS__))
4270 #define REFL_DETAIL_FOR_EACH_77(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_76
(what, __VA_ARGS__))
4271 #define REFL_DETAIL_FOR_EACH_78(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_77
(what, __VA_ARGS__))
4272 #define REFL_DETAIL_FOR_EACH_79(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_78
(what, __VA_ARGS__))
4273 #define REFL_DETAIL_FOR_EACH_80(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_79
(what, __VA_ARGS__))
4274 #define REFL_DETAIL_FOR_EACH_81(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_80
(what, __VA_ARGS__))
4275 #define REFL_DETAIL_FOR_EACH_82(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_81
(what, __VA_ARGS__))
4276 #define REFL_DETAIL_FOR_EACH_83(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_82
(what, __VA_ARGS__))
4277 #define REFL_DETAIL_FOR_EACH_84(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_83
(what, __VA_ARGS__))
4278 #define REFL_DETAIL_FOR_EACH_85(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_84
(what, __VA_ARGS__))
4279 #define REFL_DETAIL_FOR_EACH_86(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_85
(what, __VA_ARGS__))
4280 #define REFL_DETAIL_FOR_EACH_87(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_86
(what, __VA_ARGS__))
4281 #define REFL_DETAIL_FOR_EACH_88(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_87
(what, __VA_ARGS__))
4282 #define REFL_DETAIL_FOR_EACH_89(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_88
(what, __VA_ARGS__))
4283 #define REFL_DETAIL_FOR_EACH_90(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_89
(what, __VA_ARGS__))
4284 #define REFL_DETAIL_FOR_EACH_91(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_90
(what, __VA_ARGS__))
4285 #define REFL_DETAIL_FOR_EACH_92(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_91
(what, __VA_ARGS__))
4286 #define REFL_DETAIL_FOR_EACH_93(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_92
(what, __VA_ARGS__))
4287 #define REFL_DETAIL_FOR_EACH_94(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_93
(what, __VA_ARGS__))
4288 #define REFL_DETAIL_FOR_EACH_95(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_94
(what, __VA_ARGS__))
4289 #define REFL_DETAIL_FOR_EACH_96(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_95
(what, __VA_ARGS__))
4290 #define REFL_DETAIL_FOR_EACH_97(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_96
(what, __VA_ARGS__))
4291 #define REFL_DETAIL_FOR_EACH_98(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_97
(what, __VA_ARGS__))
4292 #define REFL_DETAIL_FOR_EACH_99(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_98
(what, __VA_ARGS__))
4293 #define REFL_DETAIL_FOR_EACH_100(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_99
(what, __VA_ARGS__))
4295 #define REFL_DETAIL_FOR_EACH_NARG(...) REFL_DETAIL_FOR_EACH_NARG_
(__VA_ARGS__, REFL_DETAIL_FOR_EACH_RSEQ_N
())
4296 #define REFL_DETAIL_FOR_EACH_NARG_(...) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_ARG_N
(__VA_ARGS__))
4297 #define REFL_DETAIL_FOR_EACH_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95, _96, _97, _98, _99, _100, N, ...) N
4298 #define REFL_DETAIL_FOR_EACH_RSEQ_N() 100
, 99
, 98
, 97
, 96
, 95
, 94
, 93
, 92
, 91
, 90
, 89
, 88
, 87
, 86
, 85
, 84
, 83
, 82
, 81
, 80
, 79
, 78
, 77
, 76
, 75
, 74
, 73
, 72
, 71
, 70
, 69
, 68
, 67
, 66
, 65
, 64
, 63
, 62
, 61
, 60
, 59
, 58
, 57
, 56
, 55
, 54
, 53
, 52
, 51
, 50
, 49
, 48
, 47
, 46
, 45
, 44
, 43
, 42
, 41
, 40
, 39
, 38
, 37
, 36
, 35
, 34
, 33
, 32
, 31
, 30
, 29
, 28
, 27
, 26
, 25
, 24
, 23
, 22
, 21
, 20
, 19
, 18
, 17
, 16
, 15
, 14
, 13
, 12
, 11
, 10
, 9
, 8
, 7
, 6
, 5
, 4
, 3
, 2
, 1
, 0
4299 #define REFL_DETAIL_CONCATENATE(x, y) x##y
4300 #define REFL_DETAIL_FOR_EACH_(N, what, ...) REFL_DETAIL_EXPAND
(REFL_DETAIL_CONCATENATE
(REFL_DETAIL_FOR_EACH_
, N)(what, __VA_ARGS__))
4301 #define REFL_DETAIL_FOR_EACH(what, ...) REFL_DETAIL_FOR_EACH_
(REFL_DETAIL_FOR_EACH_NARG
(__VA_ARGS__), what, __VA_ARGS__)
4306 #ifdef __INTELLISENSE__
4308 #define REFL_DETAIL_EX_1_type(X, ...) REFL_TYPE(X)
4309 #define REFL_DETAIL_EX_1_template(X, Y, ...) REFL_TEMPLATE(X, Y)
4310 #define REFL_DETAIL_EX_1_field(X, ...) REFL_FIELD(X)
4311 #define REFL_DETAIL_EX_1_func(X, ...) REFL_FUNC(X)
4315 #define REFL_DETAIL_EX_1_type(...) REFL_DETAIL_EX_EXPAND
(REFL_DETAIL_EX_DEFER
(REFL_TYPE)(__VA_ARGS__))
4316 #define REFL_DETAIL_EX_1_template(...) REFL_DETAIL_EX_EXPAND
(REFL_DETAIL_EX_DEFER
(REFL_TEMPLATE)(__VA_ARGS__))
4317 #define REFL_DETAIL_EX_1_field(...) REFL_DETAIL_EX_EXPAND
(REFL_DETAIL_EX_DEFER
(REFL_FIELD
)(__VA_ARGS__))
4318 #define REFL_DETAIL_EX_1_func(...) REFL_DETAIL_EX_EXPAND
(REFL_DETAIL_EX_DEFER
(REFL_FUNC
)(__VA_ARGS__))
4322 #define REFL_DETAIL_EX_(Specifier, ...) REFL_DETAIL_EX_1_##Specifier __VA_ARGS__
4324 #define REFL_DETAIL_EX_EMPTY()
4325 #define REFL_DETAIL_EX_DEFER(Id) Id REFL_DETAIL_EX_EMPTY
()
4326 #define REFL_DETAIL_EX_EXPAND(...) __VA_ARGS__
4328 #define REFL_DETAIL_EX_END() REFL_END
4330 #define REFL_AUTO(...) REFL_DETAIL_FOR_EACH
(REFL_DETAIL_EX_
, __VA_ARGS__) REFL_DETAIL_EX_EXPAND
(REFL_DETAIL_EX_DEFER
(REFL_DETAIL_EX_END
)())