#ifndef CTTI_SYMBOL_HPP #define CTTI_SYMBOL_HPP #include #include #include #include #include #define CTTI_DEFINE_SYMBOL(name) \ struct name { \ constexpr name() {} \ \ static constexpr ctti::detail::cstring symbol() { \ return CTTI_PP_STR(name); \ } \ \ static constexpr std::uint64_t hash() { \ return symbol().hash(); \ } \ \ template::value, typename = void> \ struct impl \ { \ static constexpr bool is_member_of() { \ return false; \ } \ \ using member_type = std::nullptr_t; \ \ static constexpr member_type get_member() { \ return nullptr; \ } \ \ static constexpr ctti::detail::cstring member_name() { \ return CTTI_PP_STR(name); \ } \ }; \ \ template \ struct impl> { \ static constexpr bool is_member_of() { \ return true; \ } \ \ using member_type = decltype(&T::name); \ \ static constexpr member_type get_member() { \ return &T::name; \ } \ \ static constexpr ctti::detail::cstring member_name() { \ return ctti::nameof(); \ } \ }; \ \ template \ struct impl> { \ static constexpr bool is_member_of() { \ return true; \ } \ \ using member_type = decltype(T::name); \ \ static constexpr member_type get_member() { \ return T::name; \ } \ \ static constexpr ctti::detail::cstring member_name() { \ return CTTI_PP_STR(name); \ } \ }; \ \ template \ using member_type = typename impl::member_type; \ \ template \ static constexpr bool is_member_of() { \ return impl::is_member_of(); \ } \ \ template \ static constexpr member_type get_member() { \ return impl::get_member(); \ } \ \ template \ static constexpr ctti::name_t detailed_name() { \ return ctti::detailed_nameof())>(); \ } \ \ template \ static constexpr ctti::detail::cstring member_name() { \ return impl::member_name(); \ } \ \ template \ using value_type = typename ::ctti::detail::member_traits>::value_type; \ }; \ \ name ctti_symbol_from_hash(::ctti::meta::uint64_t) namespace ctti { namespace detail { template struct member_traits; template struct member_traits { using value_type = T; using pointer_type = T Class::*; template static constexpr const value_type& get(const Obj& object, pointer_type member) { return object.*member; } template static constexpr value_type& get(Obj& object, pointer_type member) { return object.*member; } template static void set(Obj& object, pointer_type member, Value&& value) { get(object, member) = std::forward(value); } }; template struct member_traits { using value_type = T; using pointer_type = T (Class::*)(Args...); template static constexpr value_type get(const Obj& object, pointer_type member, _Args&&... args) { return (object.*member)(std::forward<_Args>(args)...); } template static void set(Obj& object, pointer_type member, _Args&&... args) { get(object, member, std::forward<_Args>(args)...); } }; template struct member_traits { using pointer_type = void (Class::*)(Arg); using value_type = ctti::meta::decay_t; template static void set(Obj& object, pointer_type member, _Arg&& arg) { (object.*member)(std::forward<_Arg>(arg)); } }; template struct member_traits { using value_type = T; using pointer_type = T (Class::*)(Args...) const; template static constexpr value_type get(const Obj& object, pointer_type member, _Args&&... args) { return (object.*member)(std::forward<_Args>(args)...); } }; template constexpr auto member_traits_get(const T& object, Member member, Args&&... args) -> const typename member_traits::value_type& { return member_traits::get(object, member, std::forward(args)...); } template constexpr auto member_traits_get(T& object, Member member, Args&&... args) -> typename member_traits::value_type& { return member_traits::get(object, member, std::forward(args)...); } template void member_traits_set(T& object, Member member, Args&&... args) { member_traits::set(object, member, std::forward(args)...); } template struct no_symbol_for_hash {}; } template constexpr const typename Symbol::template value_type& get_member_value(const T& object, Args&&... args) { static_assert(Symbol::template is_member_of(), "not a member of the class"); return ctti::detail::member_traits_get(object, Symbol::template get_member(), std::forward(args)...); } template typename Symbol::template value_type& get_member_value(T& object, Args&&... args) { static_assert(Symbol::template is_member_of(), "not a member of the class"); return ctti::detail::member_traits_get(object, Symbol::template get_member(), std::forward(args)...); } template void set_member_value(const T& object, Args&&... args) { static_assert(Symbol::template is_member_of(), "not a member of the class"); ctti::detail::member_traits_set(object, Symbol::template get_member(), std::forward(args)...); } template void set_member_value(T& object, Args&&... args) { static_assert(Symbol::template is_member_of(), "not a member of the class"); ctti::detail::member_traits_set(object, Symbol::template get_member(), std::forward(args)...); } } template ctti::detail::no_symbol_for_hash ctti_symbol_from_hash(Hash); #endif // CTTI_SYMBOL_HPP