23 #ifndef REFL_INCLUDE_HPP
24 #define REFL_INCLUDE_HPP
32 #include <type_traits>
39 template <
typename T,
typename Deleter>
55 #pragma warning( disable : 4003
)
58 #if defined(__clang__
)
59 #if __has_feature
(cxx_rtti)
60 #define REFL_RTTI_ENABLED
62 #elif defined(__GNUG__)
63 #if defined(__GXX_RTTI)
64 #define REFL_RTTI_ENABLED
66 #elif defined(_MSC_VER)
68 #define REFL_RTTI_ENABLED
103 #define REFL_MAKE_CONST_STRING(CString)
104 (::refl::util::detail::copy_from_unsized<::refl::util::detail::strlen(CString)>(CString))
120 static constexpr size_t
npos =
static_cast<size_t>(-1);
123 static constexpr size_t
size = N;
157 explicit constexpr operator const char*()
const noexcept
173 constexpr const char*
c_str()
const noexcept
194 template <size_t Pos, size_t Count =
npos>
197 static_assert(Pos <= N);
198 constexpr size_t NewSize =
std::min(Count, N - Pos);
200 char buf[NewSize + 1]{};
201 for (size_t i = 0; i < NewSize; i++) {
202 buf[i] =
data[Pos + i];
216 constexpr auto find(
char ch, size_t pos = 0)
const noexcept
218 for (size_t i = pos; i < N; i++) {
234 constexpr auto rfind(
char ch, size_t pos =
npos)
const noexcept
236 for (size_t i = (pos ==
npos ? N - 1 : pos); i + 1 > 0; i--) {
249 template <size_t... Idx>
250 constexpr const_string(
const const_string<N>& other,
std::index_sequence<Idx...>)
noexcept
251 :
data{ other.data[Idx]... }
258 template <size_t... Idx>
259 constexpr const_string(
const char(&data)[
sizeof...(Idx) + 1],
std::index_sequence<Idx...>)
noexcept
260 :
data{ data[Idx]... }
294 const char str[2]{ ch,
'\0' };
303 template <size_t N, size_t M>
306 char data[N + M + 1] { };
307 for (size_t i = 0; i < N; i++)
309 for (size_t i = 0; i < M; i++)
310 data[N + i] = b.data[i];
319 template <size_t N, size_t M>
322 return a + make_const_string(b);
330 template <size_t N, size_t M>
333 return make_const_string(a) + b;
341 template <size_t N, size_t M>
344 if constexpr (N != M) {
348 for (size_t i = 0; i < M; i++) {
349 if (a.data[i] != b.data[i]) {
362 template <size_t N, size_t M>
373 template <size_t N, size_t M>
376 return a == make_const_string(b);
384 template <size_t N, size_t M>
387 return a != make_const_string(b);
395 template <size_t N, size_t M>
398 return make_const_string(a) == b;
406 template <size_t N, size_t M>
409 return make_const_string(a) != b;
415 return os << str.c_str();
420 constexpr size_t strlen(
const char*
const str)
422 return *str ? 1 + strlen(str + 1) : 0;
426 constexpr const_string<N> copy_from_unsized(
const char*
const str)
429 for (size_t i = 0; i < N; i++) {
430 cstr.data[i] = str[i];
454 template <
typename... Ts>
458 static constexpr intptr_t
size =
sizeof...(Ts);
461 template <
typename T>
465 static constexpr intptr_t
size = 1;
468 template <
typename T>
473 using util::const_string;
474 using util::make_const_string;
475 using util::type_list;
476 using util::type_tag;
485 namespace macro_exports
504 using namespace refl::detail::macro_exports;
518 template <
typename T>
522 struct invalid_marker{};
527 template <size_t,
typename>
531 static constexpr size_t member_count{ 0 };
537 static constexpr std::tuple<> attributes{ };
543 template <
typename T>
544 struct type_info__<
const T> :
public type_info__<T> {};
549 template <
typename T>
550 struct type_info__<
volatile T> :
public type_info__<T> {};
555 template <
typename T>
556 struct type_info__<
const volatile T> :
public type_info__<T> {};
566 template <
typename T>
567 using type_info = refl_impl::metadata::type_info__<T>;
569 template <
typename T, size_t N>
570 using member_info =
typename type_info<T>::
template member<N>;
601 class type_descriptor;
603 template <
typename, size_t>
604 class field_descriptor;
606 template <
typename, size_t>
607 class function_descriptor;
622 template <
typename T>
633 template <
typename T>
639 template <
typename T>
640 decltype(
typename refl::detail::type_info<T>::invalid_marker{},
std::false_type{}) is_reflectable_test(
int);
643 template <
typename T>
644 std::true_type is_reflectable_test(...);
655 template <
typename T>
666 template <
typename T>
667 [[maybe_unused]]
static constexpr bool is_reflectable_v{ is_reflectable<T>::value };
672 template <
typename U>
673 [[maybe_unused]]
static auto is_container_test(
int) ->
decltype(
std::declval<U>().begin(),
std::declval<U>().end(),
std::true_type{});
676 template <
typename U>
677 [[maybe_unused]]
static std::false_type is_container_test(...);
683 template <
typename T>
691 template <
typename T>
692 [[maybe_unused]]
static constexpr bool is_container_v{ is_container<T>::value };
696 template <size_t N,
typename... Ts>
702 static_assert(N > 0,
"Missing arguments list for get<N, Ts...>!");
705 template <size_t N,
typename T,
typename... Ts>
706 struct get<N, T, Ts...> :
public get<N - 1, Ts...>
710 template <
typename T,
typename... Ts>
711 struct get<0, T, Ts...>
716 template <size_t N,
typename...>
719 template <size_t N,
typename T,
typename... Ts>
720 struct skip<N, T, Ts...> : skip<N - 1, Ts...>
724 template <
typename T,
typename... Ts>
725 struct skip<0, T, Ts...>
738 template <size_t,
typename>
750 template <size_t N,
typename... Ts>
759 template <size_t N,
typename TypeList>
760 using get_t =
typename get<N, TypeList>::type;
763 template <size_t,
typename>
775 template <size_t N,
typename... Ts>
776 struct skip<N,
type_list<Ts...>> : detail::skip<N, Ts...>
784 template <size_t N,
typename TypeList>
785 using skip_t =
typename skip<N, TypeList>::type;
800 template <
template <
typename...>
typename T,
typename... Ts>
801 struct as_type_list<T<Ts...>>
807 template <
typename T>
808 struct as_type_list : as_type_list<remove_qualifiers_t<T>>
818 template <
typename T>
819 using as_type_list_t =
typename as_type_list<T>::type;
834 template <
template <
typename...>
typename T,
typename... Ts>
835 struct as_tuple<T<Ts...>>
841 template <
typename T>
842 struct as_tuple : as_tuple<remove_qualifiers_t<T>>
852 template <
typename T>
853 using as_tuple_t =
typename as_tuple<T>::type;
858 template <
typename TypeList>
859 using first = get<0, TypeList>;
865 template <
typename TypeList>
866 using first_t =
typename first<TypeList>::type;
871 template <
typename TypeList>
872 using last = get<TypeList::size - 1, TypeList>;
878 template <
typename TypeList>
879 using last_t =
typename last<TypeList>::type;
884 template <
typename TypeList>
885 using tail = skip<1, TypeList>;
891 template <
typename TypeList>
892 using tail_t =
typename tail<TypeList>::type;
896 template <
typename, size_t,
typename>
899 template <
typename... Us>
905 template <
typename... Us,
typename T,
typename... Ts>
911 template <size_t N,
typename... Us,
typename T,
typename... Ts>
921 template <size_t N,
typename TypeList>
927 template <size_t N,
typename TypeList>
928 using take_t =
typename take<N, TypeList>::type;
933 template <
typename TypeList>
934 using init = take<TypeList::size - 1, TypeList>;
940 template <
typename TypeList>
941 using init_t =
typename init<TypeList>::type;
945 template <
typename,
typename>
948 template <
typename... Us>
954 template <
typename... Us,
typename T,
typename... Ts>
968 template <
typename TypeList>
977 template <
typename TypeList>
978 using reverse_t =
typename reverse<TypeList>::type;
987 template <
typename...>
998 template <
typename... Ts>
1008 template <
typename... Ts,
typename... Us>
1018 template <
typename TypeList1,
typename TypeList2,
typename... TypeLists>
1019 struct concat<TypeList1, TypeList2, TypeLists...> : concat<
typename concat<TypeList1, TypeList2>::type, TypeLists...>
1027 template <
typename... Ts>
1028 using concat_t =
typename concat<Ts...>::type;
1033 template <
typename T,
typename TypeList>
1042 template <
typename T,
typename TypeList>
1043 using append_t =
typename append<T, TypeList>::type;
1045 template <
typename,
typename>
1051 template <
typename T,
typename TypeList>
1052 struct prepend : concat<
type_list<T>, TypeList>
1060 template <
typename T,
typename TypeList>
1061 using prepend_t =
typename prepend<T, TypeList>::type;
1065 template <
template<
typename>
typename,
typename...>
1068 template <
template<
typename>
typename Predicate>
1069 struct filter_impl<Predicate>
1074 template <
template<
typename>
typename Predicate,
typename Head,
typename... Tail>
1075 struct filter_impl<Predicate, Head, Tail...>
1077 using type =
std::conditional_t<Predicate<Head>::value,
1078 prepend_t<Head,
typename filter_impl<Predicate, Tail...>::type>,
1079 typename filter_impl<Predicate, Tail...>::type
1083 template <
template<
typename>
typename,
typename...>
1086 template <
template<
typename>
typename Mapper>
1087 struct map_impl<Mapper>
1092 template <
template<
typename>
typename Mapper,
typename Head,
typename ...Tail>
1093 struct map_impl<Mapper, Head, Tail...>
1095 using type =
typename prepend<
typename Mapper<Head>::type,
1096 typename map_impl<Mapper, Tail...>::type>::type;
1101 template <
template<
typename>
typename,
typename>
1111 template <
template<
typename>
typename Predicate,
typename... Ts>
1114 using type =
typename detail::filter_impl<Predicate, Ts...>::type;
1122 template <
template<
typename>
typename Predicate,
typename TypeList>
1123 using filter_t =
typename filter<Predicate, TypeList>::type;
1126 template <
template<
typename>
typename,
typename>
1136 template <
template<
typename>
typename Mapper,
typename... Ts>
1139 using type =
typename detail::map_impl<Mapper, Ts...>::type;
1147 template <
template<
typename>
typename Mapper,
typename... Ts>
1148 using map_t =
typename map<Mapper, Ts...>::type;
1152 template <
typename T>
1153 struct is_instance :
public std::false_type {};
1155 template <
template<
typename...>
typename T,
typename... Args>
1156 struct is_instance<T<Args...>> :
public std::true_type {};
1168 template <
typename T>
1177 template <
typename T>
1178 [[maybe_unused]]
static constexpr bool is_instance_v{ is_instance<T>::value };
1186 template <
typename T,
template<
typename...>
typename U,
typename... Args>
1187 struct is_same_template
1189 template <
template<
typename...>
typename V,
typename = V<Args...>>
1190 static auto test(
int) ->
std::is_same<V<Args...>, T>;
1192 template <
template<
typename...>
typename V>
1193 static std::false_type test(...);
1195 static constexpr bool value{
decltype(test<U>(0))::value};
1198 template <
template<
typename...>
typename T,
typename U>
1199 struct is_instance_of :
public std::false_type {};
1201 template <
template<
typename...>
typename T,
template<
typename...>
typename U,
typename... Args>
1202 struct is_instance_of<T, U<Args...>> :
public is_same_template<U<Args...>, T, Args...>
1217 template <
template<
typename...>
typename T,
typename U>
1226 template <
template<
typename...>
typename T,
typename U>
1227 [[maybe_unused]]
static constexpr bool is_instance_of_v{ is_instance_of<T, U>::value };
1230 template <
typename,
typename>
1242 template <
typename T,
typename... Ts>
1251 template <
typename T,
typename TypeList>
1252 [[maybe_unused]]
static constexpr bool contains_v = contains<T, TypeList>::value;
1255 template <
template<
typename...>
typename,
typename>
1256 struct contains_instance;
1267 template <
template<
typename...>
typename T,
typename... Ts>
1276 template <
template<
typename...>
typename T,
typename TypeList>
1277 [[maybe_unused]]
static constexpr bool contains_instance_v = contains_instance<T, TypeList>::value;
1280 template <
typename,
typename>
1281 struct contains_base;
1295 template <
typename T,
typename... Ts>
1296 struct contains_base<T,
type_list<Ts...>> :
std::disjunction<
std::is_base_of<
std::remove_cv_t<T>,
std::remove_cv_t<Ts>>...>
1304 template <
typename T,
typename TypeList>
1305 [[maybe_unused]]
static constexpr bool contains_base_v = contains_base<T, TypeList>::value;
1309 template <
typename T, ptrdiff_t N,
typename... Ts>
1310 constexpr ptrdiff_t index_of()
noexcept
1312 if constexpr (
sizeof...(Ts) <= N)
return -1;
1313 else if constexpr (
std::is_same_v<T,
trait::get_t<N,
type_list<Ts...>>>)
return N;
1314 else return index_of<T, N + 1, Ts...>();
1317 template <
typename T, ptrdiff_t N,
typename... Ts>
1318 constexpr ptrdiff_t index_of_base()
noexcept
1320 if constexpr (
sizeof...(Ts) <= N)
return -1;
1321 else if constexpr (
std::is_base_of_v<T,
trait::get_t<N,
type_list<Ts...>>>)
return N;
1322 else return index_of_base<T, N + 1, Ts...>();
1325 template <
template<
typename...>
typename T, ptrdiff_t N,
typename... Ts>
1326 constexpr ptrdiff_t index_of_instance()
noexcept
1328 if constexpr (
sizeof...(Ts) <= N)
return -1;
1329 else if constexpr (is_instance_of_v<T,
trait::get_t<N,
type_list<Ts...>>>)
return N;
1330 else return index_of_instance<T, N + 1, Ts...>();
1335 template <
template<
typename...>
typename T, ptrdiff_t N,
typename... Ts>
1336 static constexpr ptrdiff_t index_of_instance_v = index_of_instance<T, N, Ts...>();
1340 template <
typename,
typename>
1347 template <
typename T,
typename... Ts>
1348 struct index_of<T,
type_list<Ts...>> :
std::integral_constant<ptrdiff_t, detail::index_of<T, 0, Ts...>()>
1356 template <
typename T,
typename TypeList>
1357 static constexpr ptrdiff_t index_of_v = index_of<T, TypeList>::value;
1360 template <
typename,
typename>
1361 struct index_of_base;
1367 template <
typename T,
typename... Ts>
1368 struct index_of_base<T,
type_list<Ts...>> :
std::integral_constant<ptrdiff_t, detail::index_of_base<T, 0, Ts...>()>
1376 template <
typename T,
typename TypeList>
1377 static constexpr ptrdiff_t index_of_base_v = index_of_base<T, TypeList>::value;
1380 template <
template<
typename...>
typename,
typename>
1381 struct index_of_instance;
1387 template <
template<
typename...>
typename T,
typename... Ts>
1388 struct index_of_instance<T,
type_list<Ts...>> :
std::integral_constant<ptrdiff_t, detail::index_of_instance_v<T, 0, Ts...>>
1396 template <
template<
typename...>
typename T,
typename TypeList>
1397 static constexpr ptrdiff_t index_of_instance_v = index_of_instance<T, TypeList>::value;
1401 template <
typename,
typename>
1404 template <
typename UniqueList>
1405 struct unique_impl<UniqueList,
type_list<>>
1407 using type = UniqueList;
1410 template <
typename UniqueList,
typename T,
typename... Ts>
1411 struct unique_impl<UniqueList,
type_list<T, Ts...>> :
1412 std::conditional_t<contains_v<T, UniqueList>,
1413 unique_impl<UniqueList,
type_list<Ts...>>,
1414 unique_impl<append_t<T, UniqueList>,
type_list<Ts...>>>
1426 template <
typename T>
1434 template <
typename T>
1445 template <
typename T =
int,
typename... Ts>
1455 template <
typename T>
1458 return std::forward<T>(t);
1464 template <
typename T>
1473 template <
typename T>
1484 template <
typename T,
typename... Ts>
1485 constexpr std::array<T,
sizeof...(Ts)>
to_array(
const std::tuple<Ts...>& tuple)
noexcept
1487 return std::apply([](
auto&& ... args) ->
std::array<T,
sizeof...(Ts)> {
return {
std::forward<
decltype(args)>(args)... }; }, tuple);
1494 template <
typename T>
1495 constexpr std::array<T, 0> to_array(
const std::tuple<>&)
noexcept
1502 template <
typename T, size_t... Idx>
1503 constexpr auto to_tuple([[maybe_unused]]
const std::array<T,
sizeof...(Idx)>& array,
std::index_sequence<Idx...>)
noexcept
1505 if constexpr (
sizeof...(Idx) == 0)
return std::tuple<>{};
1506 else return std::make_tuple(
std::get<Idx>(array)...);
1513 template <
typename T, size_t N>
1516 return detail::to_tuple<T>(array,
std::make_index_sequence<N>{});
1523 template <
typename... Ts>
1526 static_assert((... &&
std::is_trivial_v<Ts>),
"Non-trivial types in type_list as not allowed!");
1533 template <
typename... Ts>
1541 template <
typename F,
typename T>
1542 constexpr auto invoke_optional_index(F&& f, T&& t, size_t idx,
int) ->
decltype(f(
std::forward<T>(t), idx))
1544 return f(
std::forward<T>(t), idx);
1547 template <
typename F,
typename T>
1548 constexpr auto invoke_optional_index(F&& f, T&& t, size_t, ...) ->
decltype(f(
std::forward<T>(t)))
1550 return f(
std::forward<T>(t));
1553 template <
typename F,
typename... Carry>
1554 constexpr auto eval_in_order_to_tuple(
type_list<>,
std::index_sequence<>, F&&, Carry&&... carry)
1556 if constexpr (
sizeof...(Carry) == 0)
return std::tuple<>{};
1557 else return std::make_tuple(
std::forward<Carry>(carry)...);
1563 template <
typename F,
typename T,
typename... Ts, size_t I, size_t... Idx,
typename... Carry>
1564 constexpr auto eval_in_order_to_tuple(
type_list<T, Ts...>,
std::index_sequence<I, Idx...>, F&& f, Carry&&... carry)
1566 static_assert(
std::is_trivial_v<T>,
"Argument is a non-trivial type!");
1568 auto&& result = invoke_optional_index(f, T{}, I, 0);
1569 return eval_in_order_to_tuple(
1571 std::index_sequence<Idx...>{},
1573 std::forward<Carry>(carry)...,
1574 std::forward<
decltype(result)>(result)
1590 template <
typename F,
typename... Ts>
1593 return detail::eval_in_order_to_tuple(list,
std::make_index_sequence<
sizeof...(Ts)>{},
std::forward<F>(f));
1607 template <
typename T,
typename F,
typename... Ts>
1610 return to_array<T>(map_to_tuple(list,
std::forward<F>(f)));
1623 template <
typename F,
typename... Ts>
1626 map_to_tuple(list, [&](
auto&& val, size_t idx)
1628 detail::invoke_optional_index(f,
std::forward<
decltype(val)>(val), idx, 0);
1637 template <
typename R,
typename F,
typename... Ts>
1638 constexpr R accumulate(
type_list<>, F&&, R&& initial_value)
1640 return std::forward<R>(initial_value);
1649 template <
typename R,
typename F,
typename T,
typename... Ts>
1652 static_assert(
std::is_trivial_v<T>,
"Argument is a non-trivial type!");
1656 std::forward<
std::invoke_result_t<F&&, R&&, T&&>>(
1657 f(
std::forward<R>(initial_value), T {})));
1665 template <
typename F,
typename... Ts>
1668 return accumulate<size_t>(list,
1669 [&](size_t acc,
const auto& t) -> size_t {
return acc + (f(t) ? 1 : 0); },
1675 template <
typename F,
typename... Carry>
1681 template <
typename F,
typename T,
typename... Ts,
typename... Carry>
1684 static_assert(
std::is_trivial_v<T>,
"Argument is a non-trivial type!");
1685 if constexpr (f(T{})) {
1705 template <
typename F,
typename... Ts>
1708 return decltype(detail::filter(
std::forward<F>(f), list,
type_list<>{}))();
1715 template <
typename F,
typename... Ts>
1718 using result_list =
decltype(detail::filter(
std::forward<F>(f), list,
type_list<>{}));
1719 static_assert(result_list::size != 0,
"find_first did not match anything!");
1720 return trait::get_t<0, result_list>{};
1728 template <
typename F,
typename... Ts>
1731 using result_list =
decltype(detail::filter(
std::forward<F>(f), list,
type_list<>{}));
1732 static_assert(result_list::size != 0,
"find_one did not match anything!");
1733 static_assert(result_list::size == 1,
"Cannot resolve multiple matches in find_one!");
1734 return trait::get_t<0, result_list>{};
1741 template <
typename F,
typename T,
typename... Ts>
1744 using result_list =
decltype(detail::filter(
std::forward<F>(f), list,
type_list<>{}));
1745 return result_list::size > 0;
1752 template <
typename T,
typename... Ts>
1762 template <
typename T,
typename... Ts>
1772 template <
template <
typename...>
typename T,
typename... Ts>
1788 template <
typename... Ts,
typename F>
1795 template <size_t N,
typename... Ts>
1796 constexpr auto&
get(
std::tuple<Ts...>& ts)
noexcept
1798 return std::get<N>(ts);
1802 template <size_t N,
typename... Ts>
1803 constexpr const auto&
get(
const std::tuple<Ts...>& ts)
noexcept
1805 return std::get<N>(ts);
1809 template <
typename T,
typename... Ts>
1810 constexpr T&
get(
std::tuple<Ts...>& ts)
noexcept
1812 return std::get<T>(ts);
1816 template <
typename T,
typename... Ts>
1817 constexpr const T&
get(
const std::tuple<Ts...>& ts)
noexcept
1819 return std::get<T>(ts);
1823 template <
template<
typename...>
typename T,
typename... Ts>
1826 static_assert((... ||
trait::is_instance_of_v<T, Ts>),
"The tuple does not contain a type that is a template instance of T!");
1827 constexpr size_t idx =
static_cast<size_t>(
trait::index_of_instance_v<T,
type_list<Ts...>>);
1828 return std::get<idx>(ts);
1832 template <
template<
typename...>
typename T,
typename... Ts>
1835 static_assert((... ||
trait::is_instance_of_v<T, Ts>),
"The tuple does not contain a type that is a template instance of T!");
1836 constexpr size_t idx =
static_cast<size_t>(
trait::index_of_instance_v<T,
type_list<Ts...>>);
1837 return std::get<idx>(ts);
1847 template <
typename... Ts>
1860 template <
typename... Ts>
1947 template <
typename F>
1961 template <
typename... Ts>
1974 template <
typename... Ts>
1975 [[maybe_unused]]
static constexpr base_types<Ts...> bases{ };
1981 namespace macro_exports
1983 using attr::property;
1993 template <
typename T>
1994 auto member_type_test(
int) ->
decltype(
typename T::member_type{},
std::true_type{});
1996 template <
typename T>
1997 std::false_type member_type_test(...);
2003 template <
typename T>
2011 template <
typename T>
2012 [[maybe_unused]]
static constexpr bool is_member_v{ is_member<T>::value };
2016 template <
typename T>
2017 struct is_field_2 :
std::is_base_of<
typename T::member_type,
member::
field>
2025 template <
typename T>
2033 template <
typename T>
2034 [[maybe_unused]]
static constexpr bool is_field_v{ is_field<T>::value };
2038 template <
typename T>
2039 struct is_function_2 :
std::is_base_of<
typename T::member_type,
member::
function>
2047 template <
typename T>
2055 template <
typename T>
2056 [[maybe_unused]]
static constexpr bool is_function_v{ is_function<T>::value };
2062 template <
typename T>
2071 template <
typename T>
2077 template <
typename T>
2085 template <
typename T>
2086 [[maybe_unused]]
static constexpr bool is_descriptor_v{ is_descriptor<T>::value };
2090 template <
typename T>
2097 template <
typename T>
2098 [[maybe_unused]]
static constexpr bool is_property_v{ is_property<T>::value };
2109 template <
typename Member>
2110 struct static_field_invoker
2112 static constexpr auto invoke() ->
decltype(*Member::pointer)
2114 return *Member::pointer;
2117 template <
typename U,
typename M = Member,
std::enable_if_t<M::is_writable,
int> = 0>
2118 static constexpr auto invoke(U&& value) ->
decltype(*Member::pointer =
std::forward<U>(value))
2120 return *Member::pointer =
std::forward<U>(value);
2124 template <
typename Member>
2125 struct instance_field_invoker
2127 template <
typename T>
2128 static constexpr auto invoke(T&& target) ->
decltype(target.*(Member::pointer))
2130 return target.*(Member::pointer);
2133 template <
typename T,
typename U,
typename M = Member,
std::enable_if_t<M::is_writable,
int> = 0>
2134 static constexpr auto invoke(T&& target, U&& value) ->
decltype(target.*(Member::pointer) =
std::forward<U>(value))
2136 return target.*(Member::pointer) =
std::forward<U>(value);
2140 template <
typename Member>
2141 static_field_invoker<Member> field_type_switch(
std::true_type);
2143 template <
typename Member>
2144 instance_field_invoker<Member> field_type_switch(
std::false_type);
2146 template <
typename Member>
2147 constexpr decltype(
nullptr) get_function_pointer(...)
2152 template <
typename Member>
2153 constexpr auto get_function_pointer(
int) ->
decltype(Member::pointer())
2155 return Member::pointer();
2158 template <
typename Member,
typename Pointer>
2159 constexpr decltype(
nullptr) resolve_function_pointer(...)
2164 template <
typename Member,
typename Pointer>
2165 constexpr auto resolve_function_pointer(
int) ->
decltype(Member::
template resolve<Pointer>())
2167 return Member::
template resolve<Pointer>();
2170 template <
typename T, size_t N>
2171 using make_descriptor =
std::conditional_t<
refl::
trait::is_field_v<
refl::detail::member_info<T, N>>,
2172 field_descriptor<T, N>,
2173 std::conditional_t<
refl::
trait::is_function_v<
refl::detail::member_info<T, N>>,
2174 function_descriptor<T, N>,
2178 template <
typename T>
2181 template <
typename T, size_t... Idx>
2182 type_list<make_descriptor<T, Idx>...> enumerate_members(
std::index_sequence<Idx...>);
2184 template <
typename T>
2185 struct declared_member_list
2187 static_assert(
refl::
trait::is_reflectable_v<T>,
"This type does not support reflection!");
2188 using type =
decltype(enumerate_members<T>(
std::make_index_sequence<
refl::detail::type_info<T>::member_count>{}));
2191 template <
typename T>
2192 using attribute_types =
trait::as_type_list_t<
std::remove_cv_t<
decltype(
refl::detail::type_info<T>::attributes)>>;
2197 template <
typename... TypeLists>
2198 struct flatten<
type_list<TypeLists...>> :
trait::concat<TypeLists...>
2202 template <
typename T,
typename Base>
2203 static constexpr void validate_base()
2205 static_assert(
std::is_base_of_v<Base, T>,
"Base is not a base type of T!");
2208 template <
typename T,
typename... Bases>
2209 static constexpr void validate_bases(
type_list<Bases...>)
2211 util::ignore((validate_base<T, Bases>(), 0)...);
2214 template <
typename T>
2215 static constexpr auto get_declared_base_type_list()
2218 using base_types_type =
trait::remove_qualifiers_t<
decltype(
util::get_instance<
attr::
base_types>(
refl::detail::type_info<T>::attributes))>;
2219 validate_bases<T>(base_types_type::list);
2220 return typename base_types_type::list_type{};
2227 template <
typename T>
2228 struct declared_base_type_list
2230 using type =
decltype(get_declared_base_type_list<T>());
2233 template <
typename T>
2234 struct base_type_list;
2236 template <
typename T>
2237 static constexpr auto get_base_type_list()
2240 using declared_bases =
typename declared_base_type_list<T>::type;
2241 using rec_bases =
typename flatten<
trait::map_t<base_type_list, declared_bases>>::type;
2242 return trait::unique_t<
trait::concat_t<declared_bases, rec_bases>>{};
2249 template <
typename T>
2250 struct base_type_list
2252 using type =
decltype(get_base_type_list<T>());
2255 template <
typename T>
2256 struct member_list : flatten<
trait::map_t<declared_member_list,
trait::prepend_t<T,
typename base_type_list<T>::type>>>
2263 template <
typename T>
2264 using declared_member_list =
typename detail::declared_member_list<T>::type;
2267 template <
typename T>
2268 using member_list =
typename detail::member_list<T>::type;
2273 template <
typename T, size_t N>
2326 template <
typename T, size_t N>
2330 static_assert(
trait::is_field_v<member>);
2350 static constexpr bool is_static{ !
std::is_member_object_pointer_v<
decltype(member::pointer)> };
2366 using invoker =
decltype(detail::field_type_switch<field_descriptor>(
std::bool_constant<
is_static>{}));
2374 template <
decltype(
nullptr) =
nullptr>
2375 static constexpr decltype(
auto)
get()
noexcept
2377 return *member::pointer;
2384 template <
typename U>
2385 static constexpr decltype(
auto)
get(U&& target)
noexcept
2387 return target.*(member::pointer);
2394 template <
typename... Args>
2395 constexpr auto operator()(Args&&... args)
const noexcept ->
decltype(invoker::invoke(
std::forward<Args>(args)...))
2397 return invoker::invoke(
std::forward<Args>(args)...);
2405 template <
typename T, size_t N>
2409 static_assert(
trait::is_function_v<member>);
2419 template <
typename... Args>
2420 static constexpr auto invoke(Args&&... args) ->
decltype(member::invoke(
std::declval<Args>()...))
2422 return member::invoke(
std::forward<Args>(args)...);
2429 template <
typename... Args>
2430 using return_type =
decltype(member::invoke(
std::declval<Args>()...));
2436 template <
typename... Args>
2437 constexpr auto operator()(Args&&... args)
const ->
decltype(invoke(
std::declval<Args>()...))
2439 return invoke(
std::forward<Args>(args)...);
2446 static constexpr auto pointer{ detail::get_function_pointer<member>(0) };
2459 template <
typename Pointer>
2462 return !
std::is_same_v<
decltype(resolve<Pointer>()),
decltype(
nullptr)>;
2471 template <
typename Pointer>
2474 return detail::resolve_function_pointer<member, Pointer>(0);
2480 template <
typename T>
2481 class type_descriptor
2485 static_assert(
refl::
trait::is_reflectable_v<T>,
"This type does not support reflection!");
2487 typedef refl::detail::type_info<T> type_info;
2531 typedef detail::attribute_types<T> attribute_types;
2561 static constexpr const auto name{ type_info::name };
2586 template <
typename Descriptor>
2589 static_assert(
trait::is_descriptor_v<Descriptor>);
2603 template <
typename Descriptor>
2606 static_assert(
trait::is_descriptor_v<Descriptor>);
2607 return d.attributes;
2620 template <
typename Descriptor>
2623 static_assert(
trait::is_descriptor_v<Descriptor>);
2624 return trait::as_type_list_t<
std::remove_cv_t<
decltype(d.attributes)>>{};
2643 template <
typename TypeDescriptor>
2646 static_assert(
trait::is_type_v<TypeDescriptor>);
2647 return t.declared_bases;
2666 template <
typename TypeDescriptor>
2669 static_assert(
trait::is_type_v<TypeDescriptor>);
2687 template <
typename TypeDescriptor>
2690 static_assert(
trait::is_type_v<TypeDescriptor>);
2691 return t.declared_members;
2708 template <
typename TypeDescriptor>
2711 static_assert(
trait::is_type_v<TypeDescriptor>);
2726 template <
typename MemberDescriptor>
2729 static_assert(
trait::is_member_v<MemberDescriptor>);
2730 return d.declarator;
2751 template <
typename MemberDescriptor>
2754 static_assert(
trait::is_member_v<MemberDescriptor>);
2775 template <
typename MemberDescriptor,
typename... Args>
2776 constexpr auto invoke(MemberDescriptor d, Args&&... args)
noexcept ->
decltype(d(
std::forward<Args>(args)...))
2778 return d(
std::forward<Args>(args)...);
2794 template <
typename FieldDescriptor>
2797 static_assert(
trait::is_field_v<FieldDescriptor>);
2814 template <
typename FieldDescriptor>
2817 static_assert(
trait::is_field_v<FieldDescriptor>);
2825 template <
typename FunctionDescriptor,
typename... Args>
2826 using result_type =
typename FunctionDescriptor::
template result_type<Args...>;
2842 template <
typename FunctionDescriptor>
2845 static_assert(
trait::is_function_v<FunctionDescriptor>);
2846 return d.is_resolved;
2864 template <
typename Pointer,
typename FunctionDescriptor>
2867 static_assert(
trait::is_function_v<FunctionDescriptor>);
2868 return d.
template can_resolve<Pointer>();
2885 template <
typename Pointer,
typename FunctionDescriptor>
2886 constexpr auto resolve(FunctionDescriptor d)
noexcept
2888 static_assert(
trait::is_function_v<FunctionDescriptor>);
2889 return d.
template resolve<Pointer>();
2903 template <
typename Descriptor>
2906 static_assert(
trait::is_descriptor_v<Descriptor>);
2907 return trait::is_field_v<Descriptor>;
2921 template <
typename Descriptor>
2924 static_assert(
trait::is_descriptor_v<Descriptor>);
2925 return trait::is_function_v<Descriptor>;
2938 template <
typename Descriptor>
2941 static_assert(
trait::is_descriptor_v<Descriptor>);
2942 return trait::is_type_v<Descriptor>;
2953 template <
typename A,
typename Descriptor>
2956 static_assert(
trait::is_descriptor_v<Descriptor>);
2957 return trait::contains_base_v<A,
typename Descriptor::attribute_types>;
2968 template <
template<
typename...>
typename A,
typename Descriptor>
2969 constexpr bool has_attribute(Descriptor)
noexcept
2971 static_assert(
trait::is_descriptor_v<Descriptor>);
2972 return trait::contains_instance_v<A,
typename Descriptor::attribute_types>;
2983 template <
typename A,
typename Descriptor>
2986 static_assert(
trait::is_descriptor_v<Descriptor>);
2987 return util::get<A>(d.attributes);
2998 template <
template<
typename...>
typename A,
typename Descriptor>
3001 static_assert(
trait::is_descriptor_v<Descriptor>);
3002 return util::get_instance<A>(d.attributes);
3016 template <
typename MemberDescriptor>
3019 static_assert(
trait::is_member_v<MemberDescriptor>);
3034 template <
typename FunctionDescriptor>
3037 static_assert(
trait::is_function_v<FunctionDescriptor>);
3045 template <
typename T>
3059 template <
typename MemberDescriptor>
3062 static_assert(
trait::is_member_v<MemberDescriptor>);
3063 if constexpr (
trait::is_property_v<MemberDescriptor>) {
3064 if constexpr (
std::is_invocable_v<MemberDescriptor,
const typename MemberDescriptor::declaring_type&>) {
3065 using return_type =
typename MemberDescriptor::
template return_type<
const typename MemberDescriptor::declaring_type&>;
3066 return !
std::is_void_v<return_type>;
3073 return trait::is_field_v<MemberDescriptor>;
3087 template <
typename MemberDescriptor>
3090 static_assert(
trait::is_member_v<MemberDescriptor>);
3091 if constexpr (
trait::is_property_v<MemberDescriptor>) {
3092 return std::is_invocable_v<MemberDescriptor,
typename MemberDescriptor::declaring_type&, detail::placeholder>;
3094 else if constexpr (
trait::is_field_v<MemberDescriptor>) {
3095 return !
std::is_const_v<
typename trait::remove_qualifiers_t<MemberDescriptor>::value_type>;
3104 template <
typename T>
3105 struct get_type_descriptor
3107 typedef type_descriptor<T> type;
3123 template <
typename TypeDescriptor>
3124 [[deprecated]]
constexpr auto has_bases(TypeDescriptor t)
noexcept
3126 static_assert(
trait::is_type_v<TypeDescriptor>);
3143 template <
typename TypeDescriptor>
3144 [[deprecated]]
constexpr auto get_bases(TypeDescriptor t)
noexcept
3146 static_assert(
trait::is_type_v<TypeDescriptor>);
3147 static_assert(has_bases(t),
"Target type does not have a bases<A, B, ...> attribute.");
3150 using base_types =
typename decltype(bases)::list_type;
3151 return trait::map_t<detail::get_type_descriptor, base_types>{};
3161 template <
typename TypeDescriptor>
3164 static_assert(
trait::is_type_v<TypeDescriptor>);
3165 constexpr size_t template_start = t.name.find(
'<');
3166 constexpr size_t scope_last = t.name.rfind(
':', template_start);
3171 return t.name.
template substr<scope_last + 1, template_start - scope_last - 1>();
3183 template <
typename MemberDescriptor>
3186 static_assert(
trait::is_member_v<MemberDescriptor>);
3187 return d.declarator.name +
"::" + d.name;
3197 template <
typename MemberDescriptor>
3200 static_assert(
trait::is_member_v<MemberDescriptor>);
3201 static const std::string name(get_debug_name_const(d).str());
3202 return name.c_str();
3207 constexpr bool is_upper(
char ch)
3209 return ch >=
'A' && ch <=
'Z';
3212 constexpr char to_upper(
char ch)
3214 return ch >=
'a' && ch <=
'z'
3215 ?
char(ch + (
'A' -
'a'))
3219 constexpr char to_lower(
char ch)
3221 return ch >=
'A' && ch <=
'Z'
3222 ?
char(ch + (
'a' -
'A'))
3226 template <
typename T,
bool PreferUpper>
3227 constexpr auto normalize_bare_accessor_name()
3229 constexpr auto str = T::name.
template substr<3>();
3230 if constexpr (str.data[0] ==
'_') {
3231 return str.
template substr<1>();
3233 else if constexpr (!PreferUpper && str.data[0] >=
'A' && str.data[0] <=
'Z') {
3234 return make_const_string(to_lower(str.data[0])) + str.
template substr<1>();
3236 else if constexpr (PreferUpper) {
3237 return make_const_string(to_upper(str.data[0])) + str.
template substr<1>();
3244 template <
typename T>
3245 constexpr auto normalize_accessor_name(
const T)
3248 if constexpr (t.name.size > 3) {
3249 constexpr auto prefix = t.name.
template substr<0, 3>();
3250 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]);
3251 constexpr bool cont_pascal = is_upper(t.name.data[3]);
3253 if constexpr ((is_readable(T{}) && ((prefix ==
"Get" && cont_pascal) || (prefix ==
"get" && cont_snake_or_camel)))
3254 || (is_writable(T{}) && ((prefix ==
"Set" && cont_pascal) || (prefix ==
"set" && cont_snake_or_camel)))) {
3255 constexpr bool prefer_upper = is_upper(prefix.data[0]);
3256 return normalize_bare_accessor_name<T, prefer_upper>();
3267 template <
typename T>
3268 constexpr auto get_display_name(
const T t)
noexcept
3270 if constexpr (
trait::is_property_v<T>) {
3275 return detail::normalize_accessor_name(t);
3309 template <
typename Descriptor>
3312 static_assert(
trait::is_descriptor_v<Descriptor>);
3313 static const std::string name(detail::get_display_name(d));
3314 return name.c_str();
3322 template <
typename Descriptor>
3325 static_assert(
trait::is_descriptor_v<Descriptor>);
3326 return detail::get_display_name(d);
3335 template <
typename ReadableMember>
3338 static_assert(is_writable(member) || is_property(member));
3339 if constexpr (is_writable(member)) {
3343 return contains(get_declarator(member).members, [](
auto m) {
3344 return is_property(m) && is_writable(m) && get_display_name_const(m) == get_display_name_const(ReadableMember{});
3355 template <
typename WritableMember>
3358 static_assert(is_readable(member) || is_property(member));
3359 if constexpr (is_readable(member)) {
3363 return contains(get_declarator(member).members, [](
auto m) {
3364 return is_property(m) && is_readable(m) && get_display_name_const(m) == get_display_name_const(WritableMember{});
3375 template <
typename ReadableMember>
3378 static_assert(is_writable(member) || is_property(member));
3379 if constexpr (is_writable(member)) {
3383 static_assert(has_writer(member));
3384 return find_one(get_declarator(member).members, [](
auto m) {
3385 return is_property(m) && is_writable(m) && get_display_name_const(m) == get_display_name_const(ReadableMember{});
3396 template <
typename WritableMember>
3399 static_assert(is_readable(member) || is_property(member));
3400 if constexpr (is_readable(member)) {
3404 static_assert(has_reader(member));
3405 return find_one(get_declarator(member).members, [](
auto m) {
3406 return is_property(m) && is_readable(m) && get_display_name_const(m) == get_display_name_const(WritableMember{});
3420 template <
typename T>
3423 return trait::is_reflectable_v<T>;
3427 template <
typename T>
3430 return trait::is_reflectable_v<T>;
3434 template<
typename T>
3441 template<
typename T>
3442 constexpr type_descriptor<T>
reflect(
const T&)
noexcept
3447 #ifndef REFL_DETAIL_FORCE_EBO
3449 #define REFL_DETAIL_FORCE_EBO __declspec(empty_bases)
3451 #define REFL_DETAIL_FORCE_EBO
3460 template <
typename Derived,
typename Target>
3465 template <
typename T>
3466 struct get_member_info;
3468 template <
typename T, size_t N>
3469 struct get_member_info<
refl::function_descriptor<T, N>>
3471 using type =
refl::detail::member_info<T, N>;
3474 template <
typename T, size_t N>
3475 struct get_member_info<
refl::field_descriptor<T, N>>
3477 using type =
refl::detail::member_info<T, N>;
3480 template <
typename T,
typename U>
3481 constexpr T& static_ref_cast(U& value)
noexcept
3483 return static_cast<T&>(value);
3486 template <
typename T,
typename U>
3487 constexpr const T& static_ref_cast(
const U& value)
noexcept
3489 return static_cast<
const T&>(value);
3492 template <
typename... Results>
3498 template <
typename Member,
typename... Members,
typename... Results>
3499 constexpr auto get_members_skip_shadowed(
type_list<Member, Members...>,
type_list<Results...>)
3501 if constexpr ((... || (Results::name == Member::name))) {
3505 return get_members_skip_shadowed(
type_list<Members...>{},
type_list<Results..., Member>{});
3509 template <
typename T>
3510 using members_skip_shadowed =
decltype(get_members_skip_shadowed(member_list<T>{},
type_list<>{}));
3513 template <
typename Derived,
typename Func>
3514 struct REFL_DETAIL_FORCE_EBO function_proxy :
public get_member_info<Func>::type::
template remap<function_proxy<Derived, Func>>
3520 template <
typename Self,
typename... Args>
3521 static constexpr decltype(
auto) invoke_impl(Self&& self, Args&& ... args)
3523 return Derived::
template invoke_impl<Func>(static_ref_cast<Derived>(self),
std::forward<Args>(args)...);
3527 template <
typename,
typename>
3531 template <
typename Derived,
typename... Members>
3537 template <
typename Derived,
typename Field>
3538 struct REFL_DETAIL_FORCE_EBO field_proxy :
public get_member_info<Field>::type::
template remap<field_proxy<Derived, Field>>
3544 template <
typename Self,
typename... Args>
3545 static constexpr decltype(
auto) invoke_impl(Self&& self, Args&& ... args)
3547 return Derived::
template invoke_impl<Field>(static_ref_cast<Derived>(self),
std::forward<Args>(args)...);
3552 template <
typename,
typename>
3556 template <
typename Derived,
typename... Members>
3561 template <
typename T>
3564 template <
typename T>
3587 template <
typename Derived,
typename Target>
3589 :
public detail::function_proxies<
proxy<Derived, Target>, detail::functions<Target>>
3590 ,
public detail::field_proxies<
proxy<Derived, Target>, detail::fields<Target>>
3593 sizeof(detail::function_proxies<
proxy<Derived, Target>, detail::functions<Target>>) == 1 &&
3594 sizeof(detail::field_proxies<
proxy<Derived, Target>, detail::fields<Target>>) == 1,
3595 "Multiple inheritance EBO did not kick in! "
3596 "You could try defining the REFL_DETAIL_FORCE_EBO macro appropriately to enable it on the required types. "
3597 "Default for MSC is `__declspec(empty_bases)`.");
3600 trait::is_reflectable_v<Target>,
3601 "Target type must be reflectable!");
3609 template <
typename P,
typename F>
3610 friend struct detail::function_proxy;
3612 template <
typename P,
typename F>
3613 friend struct detail::field_proxy;
3616 template <
typename Member,
typename Self,
typename... Args>
3617 static constexpr decltype(
auto) invoke_impl(Self&& self, Args&& ... args)
3619 return Derived::
template invoke_impl<Member>(detail::static_ref_cast<Derived>(self),
std::forward<Args>(args)...);
3631 template <
typename T>
3635 template <
typename Derived,
typename Target>
3637 static std::false_type test(...);
3639 static constexpr bool value{ !
std::is_reference_v<T> &&
decltype(test(
std::declval<remove_qualifiers_t<T>*>()))::value };
3642 template <
typename T>
3643 [[maybe_unused]]
static constexpr bool is_proxy_v{ is_proxy<T>::value };
3648 template <
typename CharT,
typename T>
3649 void debug(
std::basic_ostream<CharT>& os,
const T& value,
bool compact =
false);
3653 template <
typename CharT,
typename T,
typename =
decltype(
std::declval<
std::basic_ostream<CharT>&>() <<
std::declval<T>())>
3654 std::true_type is_ostream_printable_test(
int);
3656 template <
typename CharT,
typename T>
3657 std::false_type is_ostream_printable_test(...);
3659 template <
typename CharT,
typename T>
3660 constexpr bool is_ostream_printable_v{
decltype(is_ostream_printable_test<CharT, T>(0))::value };
3664 [[maybe_unused]]
int next_depth(
int depth)
3666 return depth == -1 || depth > 8
3672 template <
typename CharT>
3673 void indent(
std::basic_ostream<CharT>& os,
int depth)
3675 for (
int i = 0; i < depth; i++) {
3680 template <
typename CharT,
typename T>
3681 void debug_impl(
std::basic_ostream<CharT>& os,
const T& value, [[maybe_unused]]
int depth);
3683 template <
typename CharT,
typename T>
3684 void debug_detailed(
std::basic_ostream<CharT>& os,
const T& value,
int depth)
3686 using type_descriptor = type_descriptor<T>;
3687 bool compact = depth == -1;
3689 os << type_descriptor::name <<
" { ";
3690 if (!compact) os <<
'\n';
3692 constexpr auto readable_members = filter(type_descriptor::members, [](
auto member) {
return is_readable(member); });
3693 for_each(readable_members, [&](
auto member, [[maybe_unused]]
auto index) {
3694 int new_depth = next_depth(depth);
3696 indent(os, new_depth);
3697 os << get_display_name(member) <<
" = ";
3699 if constexpr (
util::contains_instance<
attr::
debug>(member.attributes)) {
3701 auto debug_attr =
util::get_instance<
attr::
debug>(member.attributes);
3702 debug_attr.write(os, value);
3705 debug_impl(os, member(value), new_depth);
3708 if (!compact || index + 1 != readable_members.size) {
3717 if (compact) os <<
' ';
3722 template <
typename CharT,
typename T>
3723 void debug_reflectable(
std::basic_ostream<CharT>& os,
const T& value, [[maybe_unused]]
int depth)
3725 using type_descriptor = type_descriptor<T>;
3726 if constexpr (
trait::contains_instance_v<
attr::
debug,
typename type_descriptor::attribute_types>) {
3728 auto debug_attr =
util::get_instance<
attr::
debug>(type_descriptor::attributes);
3729 debug_attr.write(os, value);
3731 else if constexpr (detail::is_ostream_printable_v<CharT, T>) {
3736 debug_detailed(os, value, depth);
3740 template <
typename CharT,
typename T>
3741 void debug_container(
std::basic_ostream<CharT>& os,
const T& value,
int depth)
3743 bool compact = depth == -1;
3746 auto end = value.end();
3747 for (
auto it = value.begin(); it != end; ++it)
3749 if (!compact) os <<
'\n';
3750 int new_depth = next_depth(depth);
3751 indent(os, new_depth);
3753 debug_impl(os, *it, new_depth);
3754 if (
std::next(it, 1) != end) {
3757 else if (!compact) {
3766 template <
typename CharT,
typename T>
3767 void debug_impl(
std::basic_ostream<CharT>& os,
const T& value, [[maybe_unused]]
int depth)
3769 using no_pointer_t =
std::remove_pointer_t<T>;
3771 if constexpr (
std::is_same_v<
bool, T>) {
3772 os << (value ?
"true" :
"false");
3774 else if constexpr (
std::is_pointer_v<T> && !
std::is_void_v<no_pointer_t> &&
trait::is_reflectable_v<no_pointer_t>) {
3775 if (value ==
nullptr) {
3780 debug_impl(os, *value, -1);
3783 else if constexpr (
trait::is_reflectable_v<T>) {
3784 debug_reflectable(os, value, depth);
3786 else if constexpr (detail::is_ostream_printable_v<CharT, T>) {
3789 else if constexpr (
trait::is_container_v<T>) {
3790 debug_container(os, value, depth);
3793 os <<
"(not printable)";
3805 template <
typename CharT,
typename T>
3808 static_assert(
trait::is_reflectable_v<T> ||
trait::is_container_v<T> || detail::is_ostream_printable_v<CharT, T>,
3809 "Type is not reflectable, not a container of reflectable types and does not support operator<<(std::ostream&, T)!");
3811 detail::debug_impl(os, value, compact ? -1 : 0);
3817 template <
typename CharT,
typename... Ts>
3820 refl::
runtime::debug(os,
std::forward_as_tuple(
static_cast<
const Ts&>(values)...),
true);
3828 template <
typename CharT =
char,
typename T>
3831 std::basic_stringstream<CharT> ss;
3832 debug(ss, value, compact);
3839 template <
typename CharT =
char,
typename... Ts>
3842 return refl::
runtime::debug_str(
std::forward_as_tuple(
static_cast<
const Ts&>(values)...),
true);
3853 template <
typename U,
typename T,
typename... Args>
3854 U
invoke(T&& target,
const char* name, Args&&... args)
3856 using type =
std::remove_reference_t<T>;
3857 static_assert(
refl::
trait::is_reflectable_v<type>,
"Unsupported type!");
3858 typedef type_descriptor<type> type_descriptor;
3860 std::optional<U> result;
3862 bool found{
false };
3863 for_each(type_descriptor::members, [&](
auto member) {
3864 using member_t =
decltype(member);
3867 if constexpr (
std::is_invocable_r_v<U,
decltype(member), T, Args...>) {
3868 if constexpr (
trait::is_member_v<member_t>) {
3869 if (
std::strcmp(member.name.c_str(), name) == 0) {
3870 result.emplace(member(target,
std::forward<Args>(args)...));
3878 return std::move(*result);
3881 throw std::runtime_error(
std::string(
"The member ")
3882 + type_descriptor::name.str() +
"::" + name
3883 +
" is not compatible with the provided parameters or return type, is not reflected or does not exist!");
3891 namespace refl::detail
3893 constexpr bool validate_attr_unique(
type_list<>)
noexcept
3899 template <
typename T,
typename... Ts>
3900 constexpr bool validate_attr_unique(
type_list<T, Ts...>)
noexcept
3902 constexpr bool cond = (... && (!
std::is_same_v<T, Ts> && validate_attr_unique(
type_list<Ts>{})));
3903 static_assert(cond,
"Some of the attributes provided have duplicate types!");
3907 template <
typename Req,
typename Attr>
3908 constexpr bool validate_attr_usage()
noexcept
3910 return std::is_base_of_v<Req, Attr>;
3918 template <
typename Req,
typename... Args>
3919 constexpr auto make_attributes(Args&&... args)
noexcept
3921 constexpr bool check_unique = validate_attr_unique(
type_list<Args...>{});
3922 static_assert(check_unique,
"Some of the supplied attributes cannot be used on this declaration!");
3924 constexpr bool check_usage = (... && validate_attr_usage<Req,
trait::remove_qualifiers_t<Args>>());
3925 static_assert(check_usage,
"Some of the supplied attributes cannot be used on this declaration!");
3927 return std::make_tuple(
std::forward<Args>(args)...);
3930 template <
typename T,
typename...>
3940 template <
typename T,
typename... Ts>
3941 using head_t =
typename head<T, Ts...>::type;
3943 template <
typename T,
typename U>
3944 struct transfer_const
3946 using type =
std::conditional_t<
std::is_const_v<T>,
std::add_const_t<U>, U>;
3949 template <
typename T,
typename U>
3950 struct transfer_volatile
3952 using type =
std::conditional_t<
std::is_volatile_v<T>,
std::add_volatile_t<U>, U>;
3955 template <
typename T,
typename U>
3956 struct transfer_cv : transfer_const<T,
typename transfer_volatile<T, U>::type>
3960 template <
typename T,
typename U>
3961 struct transfer_lvalue_ref
3963 using type =
std::conditional_t<
std::is_lvalue_reference_v<T>,
std::add_lvalue_reference_t<U>, U>;
3966 template <
typename T,
typename U>
3967 struct transfer_rvalue_ref
3969 using type =
std::conditional_t<
std::is_rvalue_reference_v<T>,
std::add_rvalue_reference_t<U>, U>;
3972 template <
typename T,
typename U>
3973 struct transfer_ref : transfer_rvalue_ref<T,
typename transfer_lvalue_ref<T, U>::type>
3977 template <
typename T,
typename U>
3978 struct transfer_cvref : transfer_ref<T,
typename transfer_cv<
std::remove_reference_t<T>, U>::type>
3982 template <
typename T,
typename U>
3983 constexpr auto forward_cast(
std::remove_reference_t<T>& t) ->
decltype(
static_cast<
typename transfer_cvref<T, U>::type&&>(t))
3985 return static_cast<
typename transfer_cvref<T, U>::type&&>(t);
3988 template <
typename T,
typename U>
3989 constexpr auto forward_cast(
std::remove_reference_t<T>&& t) ->
decltype(
static_cast<
typename transfer_cvref<T, U>::type&&>(t))
3991 static_assert(!
std::is_lvalue_reference_v<T>,
"template argument substituting T is an lvalue reference type");
3992 return static_cast<
typename transfer_cvref<T, U>::type&&>(t);
3995 template <
typename T>
3996 constexpr auto get_type_name()
3998 if constexpr (
trait::is_reflectable_v<T>) {
3999 return type_descriptor<T>::name;
4012 #define REFL_DETAIL_STR_IMPL(...) #__VA_ARGS__
4016 #define REFL_DETAIL_GROUP(...) __VA_ARGS__
4023 #define REFL_DETAIL_ATTRIBUTES(DeclType, ...)
4024 static constexpr auto attributes{ ::refl::detail::make_attributes<::refl::attr::usage:: DeclType>(__VA_ARGS__) };
4029 #define REFL_DETAIL_TYPE_BODY(TypeName, ...)
4033 static constexpr size_t member_index_offset = __COUNTER__ + 1
;
4034 template <size_t, typename = void>
4048 #define REFL_TYPE(TypeName, ...)
4049 namespace refl_impl::metadata { template<> struct type_info__<TypeName> {
4065 #define REFL_TEMPLATE(TemplateDeclaration, TypeName, ...)
4079 static constexpr size_t member_count{ __COUNTER__ - member_index_offset };
4082 #define REFL_DETAIL_MEMBER_HEADER template<typename Unused__> struct member<__COUNTER__ - member_index_offset, Unused__>
4084 #define REFL_DETAIL_MEMBER_COMMON(MemberType_, MemberName_, ...)
4085 typedef ::refl::member::MemberType_ member_type;
4086 static constexpr auto name{ ::refl::util::make_const_string(REFL_DETAIL_STR(MemberName_)) };
4096 #define REFL_DETAIL_MEMBER_PROXY(MemberName_)
4097 template <typename Proxy> struct remap {
4098 template <typename... Args> decltype(auto) MemberName_(Args&&... args) {
4099 return Proxy::invoke_impl(static_cast<Proxy&>(*this), ::std::forward<Args>(args)...);
4101 template <typename... Args> decltype(auto) MemberName_(Args&&... args) const {
4102 return Proxy::invoke_impl(static_cast<const Proxy&>(*this), ::std::forward<Args>(args)...);
4109 #define REFL_FIELD(FieldName_, ...)
4110 REFL_DETAIL_MEMBER_HEADER
{
4111 REFL_DETAIL_MEMBER_COMMON
(field, FieldName_, __VA_ARGS__)
4113 typedef decltype(type::FieldName_) value_type;
4114 static constexpr auto pointer{ &type::FieldName_ };
4115 REFL_DETAIL_MEMBER_PROXY
(FieldName_);
4121 #define REFL_FUNC(FunctionName_, ...)
4122 REFL_DETAIL_MEMBER_HEADER
{
4123 REFL_DETAIL_MEMBER_COMMON
(function, FunctionName_, __VA_ARGS__)
4125 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)...)) {
4126 return ::refl::detail::forward_cast<Self, type>(self).FunctionName_(::std::forward<Args>(args)...);
4128 template<typename... Args> static constexpr auto invoke(Args&&... args) -> decltype(::refl::detail::head_t<type, Args...>::FunctionName_(::std::declval<Args>()...)) {
4129 return ::refl::detail::head_t<type, Args...>::FunctionName_(::std::forward<Args>(args)...);
4131 template <typename Dummy = void>
4132 static constexpr auto pointer() -> decltype(&::refl::detail::head_t<type, Dummy>::FunctionName_) { return &::refl::detail::head_t<type, Dummy>::FunctionName_; }
4133 template <typename Pointer>
4134 static constexpr auto resolve() -> ::std::decay_t<decltype(Pointer(&type::FunctionName_))> { return Pointer(&type::FunctionName_); }
4135 REFL_DETAIL_MEMBER_PROXY
(FunctionName_);
4142 #define REFL_DETAIL_PRIMITIVE(TypeName)
4147 REFL_DETAIL_PRIMITIVE(
char);
4148 REFL_DETAIL_PRIMITIVE(
wchar_t);
4149 REFL_DETAIL_PRIMITIVE(
char16_t);
4150 REFL_DETAIL_PRIMITIVE(
char32_t);
4151 #ifdef __cpp_lib_char8_t
4152 REFL_DETAIL_PRIMITIVE(char8_t);
4156 REFL_DETAIL_PRIMITIVE(
bool);
4157 REFL_DETAIL_PRIMITIVE(
signed char);
4158 REFL_DETAIL_PRIMITIVE(
unsigned char);
4159 REFL_DETAIL_PRIMITIVE(
signed short);
4160 REFL_DETAIL_PRIMITIVE(
unsigned short);
4161 REFL_DETAIL_PRIMITIVE(
signed int);
4162 REFL_DETAIL_PRIMITIVE(
unsigned int);
4163 REFL_DETAIL_PRIMITIVE(
signed long);
4164 REFL_DETAIL_PRIMITIVE(
unsigned long);
4165 REFL_DETAIL_PRIMITIVE(
signed long long);
4166 REFL_DETAIL_PRIMITIVE(
unsigned long long);
4169 REFL_DETAIL_PRIMITIVE(
float);
4170 REFL_DETAIL_PRIMITIVE(
double);
4171 REFL_DETAIL_PRIMITIVE(
long double);
4174 REFL_DETAIL_PRIMITIVE(
decltype(nullptr));
4180 #undef REFL_DETAIL_PRIMITIVE
4182 #define REFL_DETAIL_POINTER(Ptr)
4183 template<typename T>
4184 struct type_info__<T Ptr> {
4188 static constexpr auto name{ ::refl::detail::get_type_name<T>() + ::refl::util::make_const_string(#Ptr) };
4189 static constexpr ::std::tuple<> attributes{ };
4190 static constexpr size_t member_count{ 0
};
4197 REFL_DETAIL_POINTER(*);
4198 REFL_DETAIL_POINTER(&);
4199 REFL_DETAIL_POINTER(&&);
4203 #undef REFL_DETAIL_POINTER
4205 namespace refl::detail
4207 template <
typename CharT>
4208 std::basic_string<CharT> convert(
const std::string& str)
4210 return std::basic_string<CharT>(str.begin(), str.end());
4213 #ifdef __cpp_lib_string_view
4214 struct write_basic_string_view
4216 template <
typename CharT,
typename Traits>
4217 void operator()(
std::basic_ostream<CharT>& os,
std::basic_string_view<CharT, Traits> str)
const
4221 os <<
std::quoted(str.data());
4224 os <<
std::quoted(
std::basic_string<CharT, Traits>(str.begin(), str.end()));
4230 struct write_basic_string
4232 template <
typename CharT,
typename Traits,
typename Allocator>
4233 void operator()(
std::basic_ostream<CharT>& os,
const std::basic_string<CharT, Traits, Allocator>& str)
const
4235 os <<
std::quoted(str);
4239 struct write_exception
4241 template <
typename CharT>
4242 void operator()(
std::basic_ostream<CharT>& os,
const std::exception& e)
const
4244 os << convert<CharT>(
"Exception");
4245 #ifdef REFL_RTTI_ENABLED
4246 os << convert<CharT>(
" (") << convert<CharT>(
typeid(e).name()) << convert<CharT>(
")");
4248 os << convert<CharT>(
": `") << e.what() << convert<CharT>(
"`");
4254 template <
typename CharT,
typename Tuple, size_t... Idx>
4255 void write(
std::basic_ostream<CharT>& os, Tuple&& t,
std::index_sequence<Idx...>)
const
4258 for_each(
type_list<
std::integral_constant<size_t, Idx>...>{}, [&](
auto idx_c) {
4259 using idx_t =
decltype(idx_c);
4260 runtime::debug(os,
std::get<idx_t::value>(t));
4261 if constexpr (
sizeof...(Idx) - 1 != idx_t::value) {
4262 os << convert<CharT>(
", ");
4268 template <
typename CharT,
typename... Ts>
4269 void operator()(
std::basic_ostream<CharT>& os,
const std::tuple<Ts...>& t)
const
4271 write(os, t,
std::make_index_sequence<
sizeof...(Ts)>{});
4277 template <
typename CharT,
typename K,
typename V>
4278 void operator()(
std::basic_ostream<CharT>& os,
const std::pair<K, V>& t)
const
4282 os << convert<CharT>(
", ");
4288 struct write_unique_ptr
4290 template <
typename CharT,
typename T,
typename D>
4291 void operator()(
std::basic_ostream<CharT>& os,
const std::unique_ptr<T, D>& t)
const
4293 runtime::debug(os, t.get(),
true);
4297 struct write_shared_ptr
4299 template <
typename CharT,
typename T>
4300 void operator()(
std::basic_ostream<CharT>& os,
const std::shared_ptr<T>& t)
const
4302 runtime::debug(os, t.get(),
true);
4306 struct write_weak_ptr
4308 template <
typename CharT,
typename T>
4309 void operator()(
std::basic_ostream<CharT>& os,
const std::weak_ptr<T>& t)
const
4311 runtime::debug(os, t.lock().get(),
true);
4315 struct write_complex
4317 template <
typename CharT,
typename T>
4318 void operator()(
std::basic_ostream<CharT>& os,
const std::complex<T>& t)
const
4331 #ifndef REFL_NO_STD_SUPPORT
4338 (
typename Elem,
typename Traits,
typename Alloc),
4345 #ifdef __cpp_lib_string_view
4348 (
typename Elem,
typename Traits),
4364 (
typename T,
typename D),
4376 (
typename K,
typename V),
4381 #ifndef REFL_NO_STD_COMPLEX
4393 #ifndef REFL_NO_AUTO_MACRO
4395 #define REFL_DETAIL_EXPAND(x) x
4396 #define REFL_DETAIL_FOR_EACH_0(...)
4397 #define REFL_DETAIL_FOR_EACH_1(what, x, ...) what(x)
4398 #define REFL_DETAIL_FOR_EACH_2(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_1
(what, __VA_ARGS__))
4399 #define REFL_DETAIL_FOR_EACH_3(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_2
(what, __VA_ARGS__))
4400 #define REFL_DETAIL_FOR_EACH_4(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_3
(what, __VA_ARGS__))
4401 #define REFL_DETAIL_FOR_EACH_5(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_4
(what, __VA_ARGS__))
4402 #define REFL_DETAIL_FOR_EACH_6(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_5
(what, __VA_ARGS__))
4403 #define REFL_DETAIL_FOR_EACH_7(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_6
(what, __VA_ARGS__))
4404 #define REFL_DETAIL_FOR_EACH_8(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_7
(what, __VA_ARGS__))
4405 #define REFL_DETAIL_FOR_EACH_9(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_8
(what, __VA_ARGS__))
4406 #define REFL_DETAIL_FOR_EACH_10(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_9
(what, __VA_ARGS__))
4407 #define REFL_DETAIL_FOR_EACH_11(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_10
(what, __VA_ARGS__))
4408 #define REFL_DETAIL_FOR_EACH_12(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_11
(what, __VA_ARGS__))
4409 #define REFL_DETAIL_FOR_EACH_13(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_12
(what, __VA_ARGS__))
4410 #define REFL_DETAIL_FOR_EACH_14(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_13
(what, __VA_ARGS__))
4411 #define REFL_DETAIL_FOR_EACH_15(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_14
(what, __VA_ARGS__))
4412 #define REFL_DETAIL_FOR_EACH_16(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_15
(what, __VA_ARGS__))
4413 #define REFL_DETAIL_FOR_EACH_17(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_16
(what, __VA_ARGS__))
4414 #define REFL_DETAIL_FOR_EACH_18(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_17
(what, __VA_ARGS__))
4415 #define REFL_DETAIL_FOR_EACH_19(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_18
(what, __VA_ARGS__))
4416 #define REFL_DETAIL_FOR_EACH_20(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_19
(what, __VA_ARGS__))
4417 #define REFL_DETAIL_FOR_EACH_21(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_20
(what, __VA_ARGS__))
4418 #define REFL_DETAIL_FOR_EACH_22(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_21
(what, __VA_ARGS__))
4419 #define REFL_DETAIL_FOR_EACH_23(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_22
(what, __VA_ARGS__))
4420 #define REFL_DETAIL_FOR_EACH_24(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_23
(what, __VA_ARGS__))
4421 #define REFL_DETAIL_FOR_EACH_25(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_24
(what, __VA_ARGS__))
4422 #define REFL_DETAIL_FOR_EACH_26(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_25
(what, __VA_ARGS__))
4423 #define REFL_DETAIL_FOR_EACH_27(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_26
(what, __VA_ARGS__))
4424 #define REFL_DETAIL_FOR_EACH_28(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_27
(what, __VA_ARGS__))
4425 #define REFL_DETAIL_FOR_EACH_29(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_28
(what, __VA_ARGS__))
4426 #define REFL_DETAIL_FOR_EACH_30(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_29
(what, __VA_ARGS__))
4427 #define REFL_DETAIL_FOR_EACH_31(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_30
(what, __VA_ARGS__))
4428 #define REFL_DETAIL_FOR_EACH_32(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_31
(what, __VA_ARGS__))
4429 #define REFL_DETAIL_FOR_EACH_33(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_32
(what, __VA_ARGS__))
4430 #define REFL_DETAIL_FOR_EACH_34(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_33
(what, __VA_ARGS__))
4431 #define REFL_DETAIL_FOR_EACH_35(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_34
(what, __VA_ARGS__))
4432 #define REFL_DETAIL_FOR_EACH_36(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_35
(what, __VA_ARGS__))
4433 #define REFL_DETAIL_FOR_EACH_37(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_36
(what, __VA_ARGS__))
4434 #define REFL_DETAIL_FOR_EACH_38(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_37
(what, __VA_ARGS__))
4435 #define REFL_DETAIL_FOR_EACH_39(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_38
(what, __VA_ARGS__))
4436 #define REFL_DETAIL_FOR_EACH_40(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_39
(what, __VA_ARGS__))
4437 #define REFL_DETAIL_FOR_EACH_41(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_40
(what, __VA_ARGS__))
4438 #define REFL_DETAIL_FOR_EACH_42(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_41
(what, __VA_ARGS__))
4439 #define REFL_DETAIL_FOR_EACH_43(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_42
(what, __VA_ARGS__))
4440 #define REFL_DETAIL_FOR_EACH_44(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_43
(what, __VA_ARGS__))
4441 #define REFL_DETAIL_FOR_EACH_45(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_44
(what, __VA_ARGS__))
4442 #define REFL_DETAIL_FOR_EACH_46(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_45
(what, __VA_ARGS__))
4443 #define REFL_DETAIL_FOR_EACH_47(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_46
(what, __VA_ARGS__))
4444 #define REFL_DETAIL_FOR_EACH_48(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_47
(what, __VA_ARGS__))
4445 #define REFL_DETAIL_FOR_EACH_49(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_48
(what, __VA_ARGS__))
4446 #define REFL_DETAIL_FOR_EACH_50(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_49
(what, __VA_ARGS__))
4447 #define REFL_DETAIL_FOR_EACH_51(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_50
(what, __VA_ARGS__))
4448 #define REFL_DETAIL_FOR_EACH_52(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_51
(what, __VA_ARGS__))
4449 #define REFL_DETAIL_FOR_EACH_53(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_52
(what, __VA_ARGS__))
4450 #define REFL_DETAIL_FOR_EACH_54(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_53
(what, __VA_ARGS__))
4451 #define REFL_DETAIL_FOR_EACH_55(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_54
(what, __VA_ARGS__))
4452 #define REFL_DETAIL_FOR_EACH_56(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_55
(what, __VA_ARGS__))
4453 #define REFL_DETAIL_FOR_EACH_57(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_56
(what, __VA_ARGS__))
4454 #define REFL_DETAIL_FOR_EACH_58(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_57
(what, __VA_ARGS__))
4455 #define REFL_DETAIL_FOR_EACH_59(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_58
(what, __VA_ARGS__))
4456 #define REFL_DETAIL_FOR_EACH_60(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_59
(what, __VA_ARGS__))
4457 #define REFL_DETAIL_FOR_EACH_61(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_60
(what, __VA_ARGS__))
4458 #define REFL_DETAIL_FOR_EACH_62(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_61
(what, __VA_ARGS__))
4459 #define REFL_DETAIL_FOR_EACH_63(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_62
(what, __VA_ARGS__))
4460 #define REFL_DETAIL_FOR_EACH_64(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_63
(what, __VA_ARGS__))
4461 #define REFL_DETAIL_FOR_EACH_65(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_64
(what, __VA_ARGS__))
4462 #define REFL_DETAIL_FOR_EACH_66(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_65
(what, __VA_ARGS__))
4463 #define REFL_DETAIL_FOR_EACH_67(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_66
(what, __VA_ARGS__))
4464 #define REFL_DETAIL_FOR_EACH_68(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_67
(what, __VA_ARGS__))
4465 #define REFL_DETAIL_FOR_EACH_69(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_68
(what, __VA_ARGS__))
4466 #define REFL_DETAIL_FOR_EACH_70(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_69
(what, __VA_ARGS__))
4467 #define REFL_DETAIL_FOR_EACH_71(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_70
(what, __VA_ARGS__))
4468 #define REFL_DETAIL_FOR_EACH_72(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_71
(what, __VA_ARGS__))
4469 #define REFL_DETAIL_FOR_EACH_73(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_72
(what, __VA_ARGS__))
4470 #define REFL_DETAIL_FOR_EACH_74(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_73
(what, __VA_ARGS__))
4471 #define REFL_DETAIL_FOR_EACH_75(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_74
(what, __VA_ARGS__))
4472 #define REFL_DETAIL_FOR_EACH_76(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_75
(what, __VA_ARGS__))
4473 #define REFL_DETAIL_FOR_EACH_77(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_76
(what, __VA_ARGS__))
4474 #define REFL_DETAIL_FOR_EACH_78(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_77
(what, __VA_ARGS__))
4475 #define REFL_DETAIL_FOR_EACH_79(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_78
(what, __VA_ARGS__))
4476 #define REFL_DETAIL_FOR_EACH_80(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_79
(what, __VA_ARGS__))
4477 #define REFL_DETAIL_FOR_EACH_81(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_80
(what, __VA_ARGS__))
4478 #define REFL_DETAIL_FOR_EACH_82(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_81
(what, __VA_ARGS__))
4479 #define REFL_DETAIL_FOR_EACH_83(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_82
(what, __VA_ARGS__))
4480 #define REFL_DETAIL_FOR_EACH_84(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_83
(what, __VA_ARGS__))
4481 #define REFL_DETAIL_FOR_EACH_85(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_84
(what, __VA_ARGS__))
4482 #define REFL_DETAIL_FOR_EACH_86(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_85
(what, __VA_ARGS__))
4483 #define REFL_DETAIL_FOR_EACH_87(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_86
(what, __VA_ARGS__))
4484 #define REFL_DETAIL_FOR_EACH_88(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_87
(what, __VA_ARGS__))
4485 #define REFL_DETAIL_FOR_EACH_89(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_88
(what, __VA_ARGS__))
4486 #define REFL_DETAIL_FOR_EACH_90(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_89
(what, __VA_ARGS__))
4487 #define REFL_DETAIL_FOR_EACH_91(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_90
(what, __VA_ARGS__))
4488 #define REFL_DETAIL_FOR_EACH_92(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_91
(what, __VA_ARGS__))
4489 #define REFL_DETAIL_FOR_EACH_93(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_92
(what, __VA_ARGS__))
4490 #define REFL_DETAIL_FOR_EACH_94(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_93
(what, __VA_ARGS__))
4491 #define REFL_DETAIL_FOR_EACH_95(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_94
(what, __VA_ARGS__))
4492 #define REFL_DETAIL_FOR_EACH_96(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_95
(what, __VA_ARGS__))
4493 #define REFL_DETAIL_FOR_EACH_97(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_96
(what, __VA_ARGS__))
4494 #define REFL_DETAIL_FOR_EACH_98(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_97
(what, __VA_ARGS__))
4495 #define REFL_DETAIL_FOR_EACH_99(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_98
(what, __VA_ARGS__))
4496 #define REFL_DETAIL_FOR_EACH_100(what, x, ...) what(x) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_99
(what, __VA_ARGS__))
4498 #define REFL_DETAIL_FOR_EACH_NARG(...) REFL_DETAIL_FOR_EACH_NARG_
(__VA_ARGS__, REFL_DETAIL_FOR_EACH_RSEQ_N
())
4499 #define REFL_DETAIL_FOR_EACH_NARG_(...) REFL_DETAIL_EXPAND
(REFL_DETAIL_FOR_EACH_ARG_N
(__VA_ARGS__))
4500 #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
4501 #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
4502 #define REFL_DETAIL_CONCATENATE(x, y) x##y
4503 #define REFL_DETAIL_FOR_EACH_(N, what, ...) REFL_DETAIL_EXPAND
(REFL_DETAIL_CONCATENATE
(REFL_DETAIL_FOR_EACH_
, N)(what, __VA_ARGS__))
4504 #define REFL_DETAIL_FOR_EACH(what, ...) REFL_DETAIL_FOR_EACH_
(REFL_DETAIL_FOR_EACH_NARG
(__VA_ARGS__), what, __VA_ARGS__)
4509 #ifdef __INTELLISENSE__
4511 #define REFL_DETAIL_EX_1_type(X, ...) REFL_TYPE(X)
4512 #define REFL_DETAIL_EX_1_template(X, Y, ...) REFL_TEMPLATE(X, Y)
4513 #define REFL_DETAIL_EX_1_field(X, ...) REFL_FIELD(X)
4514 #define REFL_DETAIL_EX_1_func(X, ...) REFL_FUNC(X)
4518 #define REFL_DETAIL_EX_1_type(...) REFL_DETAIL_EX_EXPAND
(REFL_DETAIL_EX_DEFER
(REFL_TYPE)(__VA_ARGS__))
4519 #define REFL_DETAIL_EX_1_template(...) REFL_DETAIL_EX_EXPAND
(REFL_DETAIL_EX_DEFER
(REFL_TEMPLATE)(__VA_ARGS__))
4520 #define REFL_DETAIL_EX_1_field(...) REFL_DETAIL_EX_EXPAND
(REFL_DETAIL_EX_DEFER
(REFL_FIELD
)(__VA_ARGS__))
4521 #define REFL_DETAIL_EX_1_func(...) REFL_DETAIL_EX_EXPAND
(REFL_DETAIL_EX_DEFER
(REFL_FUNC
)(__VA_ARGS__))
4525 #define REFL_DETAIL_EX_(Specifier, ...) REFL_DETAIL_EX_1_##Specifier __VA_ARGS__
4527 #define REFL_DETAIL_EX_EMPTY()
4528 #define REFL_DETAIL_EX_DEFER(Id) Id REFL_DETAIL_EX_EMPTY
()
4529 #define REFL_DETAIL_EX_EXPAND(...) __VA_ARGS__
4531 #define REFL_DETAIL_EX_END() REFL_END
4533 #define REFL_AUTO(...) REFL_DETAIL_FOR_EACH
(REFL_DETAIL_EX_
, __VA_ARGS__) REFL_DETAIL_EX_EXPAND
(REFL_DETAIL_EX_DEFER
(REFL_DETAIL_EX_END
)())