From a9214f34358b2fc0bf61ef90e3719a13b180b423 Mon Sep 17 00:00:00 2001 From: jsmall-nvidia Date: Wed, 8 Apr 2020 10:56:00 -0400 Subject: Remove static struct members from layout and reflection (#1310) * * Added MemberFilterStyle - controls action of FilteredMemberList and FilteredMemberRefList * Splt out template implementations * Use more standard method names dofr FilteredMemberRefList * Added reflect-static.slang test * Added isNotEmpty/isEmpty to filtered lists * Added ability to index into filtered list (so not require building of array) * Default MemberFilterStyle to All. * Remove explicit MemberFilterStyle::All --- source/slang/slang-syntax.h | 211 ++++++++++++++++++++++++-------------------- 1 file changed, 115 insertions(+), 96 deletions(-) (limited to 'source/slang/slang-syntax.h') diff --git a/source/slang/slang-syntax.h b/source/slang/slang-syntax.h index 061ca4d26..db9b7284b 100644 --- a/source/slang/slang-syntax.h +++ b/source/slang/slang-syntax.h @@ -754,6 +754,43 @@ namespace Slang return DeclRef(decl, nullptr); } + enum class MemberFilterStyle + { + All, ///< All members + Instance, ///< Only instance members + Static, ///< Only static (ie non instance) members + }; + + const RefPtr* adjustFilterCursorImpl(const SyntaxClassBase::ClassInfo& clsInfo, MemberFilterStyle filterStyle, const RefPtr* ptr, const RefPtr* end); + const RefPtr* getFilterCursorByIndexImpl(const SyntaxClassBase::ClassInfo& clsInfo, MemberFilterStyle filterStyle, const RefPtr* ptr, const RefPtr* end, Index index); + Index getFilterCountImpl(const SyntaxClassBase::ClassInfo& clsInfo, MemberFilterStyle filterStyle, const RefPtr* ptr, const RefPtr* end); + + + template + const RefPtr* adjustFilterCursor(MemberFilterStyle filterStyle, const RefPtr* ptr, const RefPtr* end) + { + return adjustFilterCursorImpl(SyntaxClassBase::Impl::kClassInfo, filterStyle, ptr, end); + } + + /// Finds the element at index. If there is no element at the index (for example has too few elements), returns nullptr. + template + const RefPtr* getFilterCursorByIndex(MemberFilterStyle filterStyle, const RefPtr* ptr, const RefPtr* end, Index index) + { + return getFilterCursorByIndexImpl(SyntaxClassBase::Impl::kClassInfo, filterStyle, ptr, end, index); + } + + template + Index getFilterCount(MemberFilterStyle filterStyle, const RefPtr* ptr, const RefPtr* end) + { + return getFilterCountImpl(SyntaxClassBase::Impl::kClassInfo, filterStyle, ptr, end); + } + + template + bool isFilterNonEmpty(MemberFilterStyle filterStyle, const RefPtr* ptr, const RefPtr* end) + { + return adjustFilterCursorImpl(SyntaxClassBase::Impl::kClassInfo, filterStyle, ptr, end) != end; + } + template struct FilteredMemberList { @@ -765,69 +802,59 @@ namespace Slang {} explicit FilteredMemberList( - List const& list) - : m_begin(adjust(list.begin(), list.end())) + List const& list, + MemberFilterStyle filterStyle = MemberFilterStyle::All) + : m_begin(adjustFilterCursor(filterStyle, list.begin(), list.end())) , m_end(list.end()) + , m_filterStyle(filterStyle) {} struct Iterator { const Element* m_cursor; const Element* m_end; + MemberFilterStyle m_filterStyle; - bool operator!=(Iterator const& other) - { - return m_cursor != other.m_cursor; - } + bool operator!=(Iterator const& other) const { return m_cursor != other.m_cursor; } - void operator++() - { - m_cursor = adjust(m_cursor + 1, m_end); - } + void operator++() { m_cursor = adjustFilterCursor(m_filterStyle, m_cursor + 1, m_end); } - const RefPtr& operator*() - { - return *(RefPtr*)(m_cursor); - } + const RefPtr& operator*() { return *(RefPtr*)(m_cursor); } }; Iterator begin() { - Iterator iter = { m_begin, m_end }; + Iterator iter = { m_begin, m_end, m_filterStyle }; return iter; } Iterator end() { - Iterator iter = { m_end, m_end }; + Iterator iter = { m_end, m_end, m_filterStyle }; return iter; } - static const Element* adjust(const Element* cursor, const Element* end) - { - while (cursor != end) - { - if (as(*cursor)) - return cursor; - cursor++; - } - return cursor; - } - // TODO(tfoley): It is ugly to have these. // We should probably fix the call sites instead. const RefPtr& getFirst() { return *begin(); } - Index getCount() + Index getCount() { return getFilterCount(m_filterStyle, m_begin, m_end); } + + RefPtr operator[](Index index) const { - Index count = 0; - for (auto iter : (*this)) - { - (void)iter; - count++; - } - return count; + const RefPtr* ptr = getFilterCursorByIndex(m_filterStyle, m_begin, m_end, index); + SLANG_ASSERT(ptr); + return *(RefPtr*)(ptr); } + /// Returns true if empty (equivalent to getCount() == 0) + bool isEmpty() const + { + /// Note we don't have to scan, because m_begin has already been adjusted, when the FilteredMemberList is constructed + return m_begin == m_end; + } + /// Returns true if non empty (equivalent to getCount() != 0 but faster) + bool isNonEmpty() const { return !isEmpty(); } + List> toArray() { List> result; @@ -837,12 +864,10 @@ namespace Slang } return result; } - - bool isEmpty() const { return m_end == m_begin; } - bool isNonEmpty() const { return m_end != m_begin; } - - const Element* m_begin; + + const Element* m_begin; ///< Is either equal to m_end, or points to first *valid* filtered member const Element* m_end; + MemberFilterStyle m_filterStyle; }; struct TransparentMemberInfo @@ -854,25 +879,34 @@ namespace Slang template struct FilteredMemberRefList { - List> const& decls; - SubstitutionSet substitutions; + List> const& m_decls; + SubstitutionSet m_substitutions; + MemberFilterStyle m_filterStyle; FilteredMemberRefList( List> const& decls, - SubstitutionSet substitutions) - : decls(decls) - , substitutions(substitutions) + SubstitutionSet substitutions, + MemberFilterStyle filterStyle = MemberFilterStyle::All) + : m_decls(decls) + , m_substitutions(substitutions) + , m_filterStyle(filterStyle) {} - int Count() const + Index getCount() const { return getFilterCount(m_filterStyle, m_decls.begin(), m_decls.end()); } + + /// True if empty (equivalent to getCount == 0, but faster) + bool isEmpty() const { return !isNonEmpty(); } + /// True if non empty (equivalent to getCount() != 0 but faster) + bool isNonEmpty() const { return isFilterNonEmpty(m_filterStyle, m_decls.begin(), m_decls.end()); } + + DeclRef operator[](Index index) const { - int count = 0; - for (auto d : *this) - count++; - return count; + const RefPtr* decl = getFilterCursorByIndex(m_filterStyle, m_decls.begin(), m_decls.end(), index); + SLANG_ASSERT(decl); + return DeclRef((T*) decl->Ptr(), m_substitutions); } - List> ToArray() const + List> toArray() const { List> result; for (auto d : *this) @@ -882,50 +916,33 @@ namespace Slang struct Iterator { - FilteredMemberRefList const* list; - const RefPtr* ptr; - const RefPtr* end; + FilteredMemberRefList const* m_list; + const RefPtr* m_ptr; + const RefPtr* m_end; + MemberFilterStyle m_filterStyle; - Iterator() : list(nullptr), ptr(nullptr) {} + Iterator() : m_list(nullptr), m_ptr(nullptr), m_filterStyle(MemberFilterStyle::All) {} Iterator( - FilteredMemberRefList const* inList, - const RefPtr* inPtr, - const RefPtr* inEnd) - : list(inList) - , ptr(inPtr) - , end(inEnd) + FilteredMemberRefList const* list, + const RefPtr* ptr, + const RefPtr* end, + MemberFilterStyle filterStyle + ) + : m_list(list) + , m_ptr(ptr) + , m_end(end) + , m_filterStyle(filterStyle) {} - bool operator!=(Iterator other) - { - return ptr != other.ptr; - } + bool operator!=(const Iterator& other) const { return m_ptr != other.m_ptr; } - void operator++() - { - ptr = list->Adjust(ptr + 1, end); - } + void operator++() { m_ptr = adjustFilterCursor(m_filterStyle, m_ptr + 1, m_end); } - DeclRef operator*() - { - return DeclRef((T*) ptr->Ptr(), list->substitutions); - } + DeclRef operator*() { return DeclRef((T*) m_ptr->Ptr(), m_list->m_substitutions); } }; - Iterator begin() const { return Iterator(this, Adjust(decls.begin(), decls.end()), decls.end()); } - Iterator end() const { return Iterator(this, decls.end(), decls.end()); } - - const RefPtr* Adjust(const RefPtr* ptr, const RefPtr* end) const - { - for (; ptr != end; ptr++) - { - if (ptr->is()) - { - return ptr; - } - } - return end; - } + Iterator begin() const { return Iterator(this, adjustFilterCursor(m_filterStyle, m_decls.begin(), m_decls.end()), m_decls.end(), m_filterStyle); } + Iterator end() const { return Iterator(this, m_decls.end(), m_decls.end(), m_filterStyle); } }; // @@ -1400,28 +1417,28 @@ namespace Slang return declRef.getDecl()->candidateExtensions; } - inline FilteredMemberRefList getMembers(DeclRef const& declRef) + inline FilteredMemberRefList getMembers(DeclRef const& declRef, MemberFilterStyle filterStyle = MemberFilterStyle::All) { - return FilteredMemberRefList(declRef.getDecl()->Members, declRef.substitutions); + return FilteredMemberRefList(declRef.getDecl()->Members, declRef.substitutions, filterStyle); } template - inline FilteredMemberRefList getMembersOfType(DeclRef const& declRef) + inline FilteredMemberRefList getMembersOfType( DeclRef const& declRef, MemberFilterStyle filterStyle = MemberFilterStyle::All) { - return FilteredMemberRefList(declRef.getDecl()->Members, declRef.substitutions); + return FilteredMemberRefList(declRef.getDecl()->Members, declRef.substitutions, filterStyle); } template - inline List> getMembersOfTypeWithExt(DeclRef const& declRef) + inline List> getMembersOfTypeWithExt(DeclRef const& declRef, MemberFilterStyle filterStyle = MemberFilterStyle::All) { List> rs; - for (auto d : getMembersOfType(declRef)) + for (auto d : getMembersOfType(declRef, filterStyle)) rs.add(d); if (auto aggDeclRef = declRef.as()) { for (auto ext = GetCandidateExtensions(aggDeclRef); ext; ext = ext->nextCandidateExtension) { - auto extMembers = getMembersOfType(DeclRef(ext, declRef.substitutions)); + auto extMembers = getMembersOfType(DeclRef(ext, declRef.substitutions), filterStyle); for (auto mbr : extMembers) rs.add(mbr); } @@ -1469,11 +1486,13 @@ namespace Slang return declRef.Substitute(declRef.getDecl()->targetType.Ptr()); } - inline FilteredMemberRefList GetFields(DeclRef const& declRef) + inline FilteredMemberRefList GetFields(DeclRef const& declRef, MemberFilterStyle filterStyle) { - return getMembersOfType(declRef); + return getMembersOfType(declRef, filterStyle); } + + inline RefPtr getBaseType(DeclRef const& declRef) { return declRef.Substitute(declRef.getDecl()->base.type); -- cgit v1.2.3