#pragma once #include #ifdef UTEMPL_MODULE export module utempl.meta_info; import utempl.loopholes; import utempl.type_list; import std; #else #include #include #endif namespace utempl { UTEMPL_EXPORT struct Types {}; UTEMPL_EXPORT template struct MetaInfoKey {}; UTEMPL_EXPORT template struct MetaInfo { static constexpr std::size_t kTypeId = loopholes::Counter(); using Type = T; private: static constexpr auto _ = loopholes::Injector{}, TypeList{}>{}; }; UTEMPL_EXPORT template inline constexpr std::size_t kTypeId = MetaInfo::kTypeId; UTEMPL_EXPORT template (), auto = loopholes::Injector{}, TypeList{}>{}> consteval auto AddTypeToTag(TTs&&...) -> std::size_t { return Id; }; UTEMPL_EXPORT template using GetMetaInfo = MetaInfo{}>{}))::Type>; UTEMPL_EXPORT template using GetType = GetMetaInfo::Type; template static consteval auto GetTypeListForTag(G g) requires(I == 0 || requires { Magic(loopholes::Getter{}>{}); }) { if constexpr(I == 0 && !requires { Magic(loopholes::Getter{}>{}); }) { return TypeList{}; } else { if constexpr(requires { GetTypeListForTag(g); }) { constexpr auto type = Magic(loopholes::Getter{}>{}); return GetTypeListForTag(g); } else { constexpr auto type = Magic(loopholes::Getter{}>{}); return TypeList(); }; }; }; UTEMPL_EXPORT template consteval auto GetTypeListForTag() { return GetTypeListForTag(TypeList{}); }; UTEMPL_EXPORT template () - 1> consteval auto GetCurrentTagType() { return Magic(utempl::loopholes::Getter{}>()); }; /* static_assert(kTypeId == 0); static_assert(kTypeId == 1); static_assert(AddTypeToTag() == 2); static_assert(std::is_same_v>); */ } // namespace utempl