export module utempl.attributes; export import utempl.meta_info; export import utempl.tuple; export import utempl.loopholes.counter; import utempl.utils; import utempl.type_list; namespace utempl { namespace impl { export struct AttributesTag {}; export template struct AttributesCounterTag {}; } // namespace impl export template ()> consteval auto OpenStruct() -> bool { return true; }; export template (), auto II = (I >= 2) ? I - 2 : I - 1, typename T = decltype(Magic(loopholes::Getter{}>{}))::Type, auto = AddTypeToTag()> consteval auto CloseStruct() -> bool { return true; }; export struct NoInfo { consteval auto operator==(const NoInfo&) const -> bool = default; }; template struct FieldAttributeData { using Type = TypeList; }; template <> struct FieldAttributeData<> { using Type = NoInfo; }; template ())::Type, auto = AddTypeToTag, typename FieldAttributeData::Type, decltype(f)>()> consteval auto FieldAttributeHelper() -> T; export template using FieldAttribute = decltype(FieldAttributeHelper()); export template , decltype(f)>() > 0)> concept HasAttributes = R; export template concept HasMacroAttributes = requires { T::template GetAttribute<0>(); }; export template consteval auto GetAttributes() requires HasMacroAttributes { constexpr auto I = loopholes::CountValue>(); return [](auto... is) { return Tuple{T::template GetAttribute()...}; } | kSeq; }; export template consteval auto GetAttributes() { constexpr auto I = loopholes::CountValue>(); return [](auto... is) { return utempl::Tuple{typename decltype(Magic(loopholes::Getter>{}>{}))::Type{}...}; } | kSeq; }; } // namespace utempl