diff options
| author | Bryan Galdrikian <[email protected]> | 2017-02-24 09:32:20 -0800 |
|---|---|---|
| committer | Bryan Galdrikian <[email protected]> | 2017-02-24 09:32:20 -0800 |
| commit | e1bf674c16e3c8472b29574159c789cd3f0c64e0 (patch) | |
| tree | 9f0cfce09c71a2c27ff19589fcad6cd83504477c /sdk/common/NvBlastDLink.h | |
| parent | first commit (diff) | |
| download | blast-e1bf674c16e3c8472b29574159c789cd3f0c64e0.tar.xz blast-e1bf674c16e3c8472b29574159c789cd3f0c64e0.zip | |
Updating to [email protected] and [email protected] with a new directory structure.
NvBlast folder is gone, files have been moved to top level directory. README is changed to reflect this.
Diffstat (limited to 'sdk/common/NvBlastDLink.h')
| -rw-r--r-- | sdk/common/NvBlastDLink.h | 285 |
1 files changed, 285 insertions, 0 deletions
diff --git a/sdk/common/NvBlastDLink.h b/sdk/common/NvBlastDLink.h new file mode 100644 index 0000000..bfcee24 --- /dev/null +++ b/sdk/common/NvBlastDLink.h @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. + * + * NVIDIA CORPORATION and its licensors retain all intellectual property + * and proprietary rights in and to this software, related documentation + * and any modifications thereto. Any use, reproduction, disclosure or + * distribution of this software and related documentation without an express + * license agreement from NVIDIA CORPORATION is strictly prohibited. + */ + +#ifndef NVBLASTDLINK_H +#define NVBLASTDLINK_H + + +#include "NvBlastAssert.h" +#include "NvBlastIndexFns.h" + + +namespace Nv +{ +namespace Blast +{ + +template<typename IndexType> +struct IndexDLink +{ + IndexType m_adj[2]; +}; + + +template<typename IndexType> +class IndexDList +{ +public: + void initLinksSolitary(IndexDLink<IndexType>* links, IndexType linkCount) + { + for (IndexType i = 0; i < linkCount; ++i) + { + links[i].m_adj[0] = invalidIndex<IndexType>(); + links[i].m_adj[1] = invalidIndex<IndexType>(); + } + } + + void initLinksChain(IndexDLink<IndexType>* links, IndexType linkCount) + { + if (linkCount > 0) + { + links[0].m_adj[0] = invalidIndex<IndexType>(); + for (IndexType i = 1; i < linkCount; ++i) + { + links[i - 1].m_adj[1] = i; + links[i].m_adj[0] = i - 1; + } + links[linkCount - 1].m_adj[1] = invalidIndex<IndexType>(); + } + } + + IndexType getAdj(IndexDLink<IndexType>* links, IndexType linkIndex, int which) + { + return links[linkIndex].m_adj[which & 1]; + } + + void remove(IndexDLink<IndexType>* links, IndexType linkIndex) + { + IndexDLink<IndexType>& link = links[linkIndex]; + const IndexType adj0 = link.m_adj[0]; + const IndexType adj1 = link.m_adj[1]; + if (!isInvalidIndex(adj1)) + { + links[adj1].m_adj[0] = adj0; + link.m_adj[1] = invalidIndex<IndexType>(); + } + if (!isInvalidIndex(adj0)) + { + links[adj0].m_adj[1] = adj1; + link.m_adj[0] = invalidIndex<IndexType>(); + } + } + + bool isSolitary(IndexDLink<IndexType>* links, IndexType linkIndex) + { + const IndexDLink<IndexType>& link = links[linkIndex]; + return isInvalidIndex(link.m_adj[0]) && isInvalidIndex(link.m_adj[1]); + } + + void insertListHead(IndexType& listHead, IndexDLink<IndexType>* links, IndexType linkIndex) + { + NVBLAST_ASSERT(!isInvalidIndex(linkIndex)); + if (!isInvalidIndex(listHead)) + { + links[listHead].m_adj[0] = linkIndex; + } + links[linkIndex].m_adj[1] = listHead; + listHead = linkIndex; + } + + IndexType removeListHead(IndexType& listHead, IndexDLink<IndexType>* links) + { + const IndexType linkIndex = listHead; + if (!isInvalidIndex(linkIndex)) + { + listHead = links[linkIndex].m_adj[1]; + if (!isInvalidIndex(listHead)) + { + links[listHead].m_adj[0] = invalidIndex<IndexType>(); + } + links[linkIndex].m_adj[1] = invalidIndex<IndexType>(); + } + return linkIndex; + } + + void removeFromList(IndexType& listHead, IndexDLink<IndexType>* links, IndexType linkIndex) + { + NVBLAST_ASSERT(!isInvalidIndex(linkIndex)); + if (listHead == linkIndex) + { + listHead = links[linkIndex].m_adj[1]; + } + remove(links, linkIndex); + } +}; + + +struct DLink +{ + DLink() : m_prev(nullptr), m_next(nullptr) {} + + DLink* getPrev() const + { + return m_prev; + } + + DLink* getNext() const + { + return m_next; + } + +private: + DLink* m_prev; + DLink* m_next; + + friend class DList; +}; + + +class DList +{ +public: + DList() : m_head(nullptr), m_tail(nullptr) {} + + bool isEmpty() const + { + NVBLAST_ASSERT((m_head == nullptr) == (m_tail == nullptr)); + return m_head == nullptr; + } + + bool isSolitary(const DLink& link) const + { + return link.m_prev == nullptr && link.m_next == nullptr && m_head != &link; + } + + DLink* getHead() const + { + return m_head; + } + + DLink* getTail() const + { + return m_tail; + } + + bool insertHead(DLink& link) + { + NVBLAST_ASSERT(isSolitary(link)); + if (!isSolitary(link)) + { + return false; + } + + link.m_next = m_head; + if (m_head != nullptr) + { + m_head->m_prev = &link; + } + m_head = &link; + if (m_tail == nullptr) + { + m_tail = &link; + } + + return true; + } + + bool insertTail(DLink& link) + { + NVBLAST_ASSERT(isSolitary(link)); + if (!isSolitary(link)) + { + return false; + } + + link.m_prev = m_tail; + if (m_tail != nullptr) + { + m_tail->m_next = &link; + } + m_tail = &link; + if (m_head == nullptr) + { + m_head = &link; + } + + return true; + } + + void remove(DLink& link) + { + if (link.m_prev != nullptr) + { + link.m_prev->m_next = link.m_next; + } + else + if (m_head == &link) + { + m_head = link.m_next; + } + + if (link.m_next != nullptr) + { + link.m_next->m_prev = link.m_prev; + } + else + if (m_tail == &link) + { + m_tail = link.m_prev; + } + + link.m_next = link.m_prev = nullptr; + } + + class It + { + public: + enum Direction { Reverse, Forward }; + + It(const DList& list, Direction dir = Forward) : m_curr(dir == Forward ? list.getHead() : list.getTail()) {} + + /** Validity of current value. */ + operator bool() const + { + return m_curr != nullptr; + } + + /** Current value. */ + operator const DLink*() const + { + return m_curr; + } + + /** Pre-increment. */ + const DLink* operator ++ () + { + return m_curr = m_curr->getNext(); + } + + /** Pre-deccrement. */ + const DLink* operator -- () + { + return m_curr = m_curr->getPrev(); + } + + private: + const DLink* m_curr; + }; + +private: + DLink* m_head; + DLink* m_tail; +}; + +} // end namespace Blast +} // end namespace Nv + + +#endif // #ifndef NVBLASTDLINK_H |