Main Page   Class List   Class Members  

  • Main Page
  • User's Guide
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

sdk/common/NvBlastDLink.h

Go to the documentation of this file.
00001 // This code contains NVIDIA Confidential Information and is disclosed to you
00002 // under a form of NVIDIA software license agreement provided separately to you.
00003 //
00004 // Notice
00005 // NVIDIA Corporation and its licensors retain all intellectual property and
00006 // proprietary rights in and to this software and related documentation and
00007 // any modifications thereto. Any use, reproduction, disclosure, or
00008 // distribution of this software and related documentation without an express
00009 // license agreement from NVIDIA Corporation is strictly prohibited.
00010 //
00011 // ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
00012 // NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
00013 // THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
00014 // MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
00015 //
00016 // Information and code furnished is believed to be accurate and reliable.
00017 // However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
00018 // information or for any infringement of patents or other rights of third parties that may
00019 // result from its use. No license is granted by implication or otherwise under any patent
00020 // or patent rights of NVIDIA Corporation. Details are subject to change without notice.
00021 // This code supersedes and replaces all information previously supplied.
00022 // NVIDIA Corporation products are not authorized for use as critical
00023 // components in life support devices or systems without express written approval of
00024 // NVIDIA Corporation.
00025 //
00026 // Copyright (c) 2016-2020 NVIDIA Corporation. All rights reserved.
00027 
00028 
00029 #ifndef NVBLASTDLINK_H
00030 #define NVBLASTDLINK_H
00031 
00032 
00033 #include "NvBlastAssert.h"
00034 #include "NvBlastIndexFns.h"
00035 
00036 
00037 namespace Nv
00038 {
00039 namespace Blast
00040 {
00041 
00042 template<typename IndexType>
00043 struct IndexDLink
00044 {
00045     IndexType   m_adj[2];
00046 };
00047 
00048 
00049 template<typename IndexType>
00050 class IndexDList
00051 {
00052 public:
00053     void        initLinksSolitary(IndexDLink<IndexType>* links, IndexType linkCount)
00054     {
00055         for (IndexType i = 0; i < linkCount; ++i)
00056         {
00057             links[i].m_adj[0] = invalidIndex<IndexType>();
00058             links[i].m_adj[1] = invalidIndex<IndexType>();
00059         }
00060     }
00061 
00062     void        initLinksChain(IndexDLink<IndexType>* links, IndexType linkCount)
00063     {
00064         if (linkCount > 0)
00065         {
00066             links[0].m_adj[0] = invalidIndex<IndexType>();
00067             for (IndexType i = 1; i < linkCount; ++i)
00068             {
00069                 links[i - 1].m_adj[1] = i;
00070                 links[i].m_adj[0] = i - 1;
00071             }
00072             links[linkCount - 1].m_adj[1] = invalidIndex<IndexType>();
00073         }
00074     }
00075 
00076     IndexType   getAdj(IndexDLink<IndexType>* links, IndexType linkIndex, int which)
00077     {
00078         return links[linkIndex].m_adj[which & 1];
00079     }
00080 
00081     void        remove(IndexDLink<IndexType>* links, IndexType linkIndex)
00082     {
00083         IndexDLink<IndexType>& link = links[linkIndex];
00084         const IndexType adj0 = link.m_adj[0];
00085         const IndexType adj1 = link.m_adj[1];
00086         if (!isInvalidIndex(adj1))
00087         {
00088             links[adj1].m_adj[0] = adj0;
00089             link.m_adj[1] = invalidIndex<IndexType>();
00090         }
00091         if (!isInvalidIndex(adj0))
00092         {
00093             links[adj0].m_adj[1] = adj1;
00094             link.m_adj[0] = invalidIndex<IndexType>();
00095         }
00096     }
00097 
00098     bool        isSolitary(IndexDLink<IndexType>* links, IndexType linkIndex)
00099     {
00100         const IndexDLink<IndexType>& link = links[linkIndex];
00101         return isInvalidIndex(link.m_adj[0]) && isInvalidIndex(link.m_adj[1]);
00102     }
00103 
00104     void        insertListHead(IndexType& listHead, IndexDLink<IndexType>* links, IndexType linkIndex)
00105     {
00106         NVBLAST_ASSERT(!isInvalidIndex(linkIndex));
00107         if (!isInvalidIndex(listHead))
00108         {
00109             links[listHead].m_adj[0] = linkIndex;
00110         }
00111         links[linkIndex].m_adj[1] = listHead;
00112         listHead = linkIndex;
00113     }
00114 
00115     IndexType   removeListHead(IndexType& listHead, IndexDLink<IndexType>* links)
00116     {
00117         const IndexType linkIndex = listHead;
00118         if (!isInvalidIndex(linkIndex))
00119         {
00120             listHead = links[linkIndex].m_adj[1];
00121             if (!isInvalidIndex(listHead))
00122             {
00123                 links[listHead].m_adj[0] = invalidIndex<IndexType>();
00124             }
00125             links[linkIndex].m_adj[1] = invalidIndex<IndexType>();
00126         }
00127         return linkIndex;
00128     }
00129 
00130     void        removeFromList(IndexType& listHead, IndexDLink<IndexType>* links, IndexType linkIndex)
00131     {
00132         NVBLAST_ASSERT(!isInvalidIndex(linkIndex));
00133         if (listHead == linkIndex)
00134         {
00135             listHead = links[linkIndex].m_adj[1];
00136         }
00137         remove(links, linkIndex);
00138     }
00139 };
00140 
00141 
00142 struct DLink
00143 {
00144     DLink() : m_prev(nullptr), m_next(nullptr) {}
00145 
00146     DLink*  getPrev() const
00147     {
00148         return m_prev;
00149     }
00150 
00151     DLink*  getNext() const
00152     {
00153         return m_next;
00154     }
00155 
00156 private:
00157     DLink*  m_prev;
00158     DLink*  m_next;
00159 
00160     friend class DList;
00161 };
00162 
00163 
00164 class DList
00165 {
00166 public:
00167     DList() : m_head(nullptr), m_tail(nullptr) {}
00168 
00169     bool    isEmpty() const
00170     {
00171         NVBLAST_ASSERT((m_head == nullptr) == (m_tail == nullptr));
00172         return m_head == nullptr;
00173     }
00174 
00175     bool    isSolitary(const DLink& link) const
00176     {
00177         return link.m_prev == nullptr && link.m_next == nullptr && m_head != &link;
00178     }
00179 
00180     DLink*  getHead() const
00181     {
00182         return m_head;
00183     }
00184 
00185     DLink*  getTail() const
00186     {
00187         return m_tail;
00188     }
00189 
00190     bool    insertHead(DLink& link)
00191     {
00192         NVBLAST_ASSERT(isSolitary(link));
00193         if (!isSolitary(link))
00194         {
00195             return false;
00196         }
00197 
00198         link.m_next = m_head;
00199         if (m_head != nullptr)
00200         {
00201             m_head->m_prev = &link;
00202         }
00203         m_head = &link;
00204         if (m_tail == nullptr)
00205         {
00206             m_tail = &link;
00207         }
00208 
00209         return true;
00210     }
00211 
00212     bool    insertTail(DLink& link)
00213     {
00214         NVBLAST_ASSERT(isSolitary(link));
00215         if (!isSolitary(link))
00216         {
00217             return false;
00218         }
00219 
00220         link.m_prev = m_tail;
00221         if (m_tail != nullptr)
00222         {
00223             m_tail->m_next = &link;
00224         }
00225         m_tail = &link;
00226         if (m_head == nullptr)
00227         {
00228             m_head = &link;
00229         }
00230 
00231         return true;
00232     }
00233 
00234     void    remove(DLink& link)
00235     {
00236         if (link.m_prev != nullptr)
00237         {
00238             link.m_prev->m_next = link.m_next;
00239         }
00240         else
00241         if (m_head == &link)
00242         {
00243             m_head = link.m_next;
00244         }
00245 
00246         if (link.m_next != nullptr)
00247         {
00248             link.m_next->m_prev = link.m_prev;
00249         }
00250         else
00251         if (m_tail == &link)
00252         {
00253             m_tail = link.m_prev;
00254         }
00255 
00256         link.m_next = link.m_prev = nullptr;
00257     }
00258 
00259     class It
00260     {
00261     public:
00262         enum Direction { Reverse, Forward };
00263 
00264         It(const DList& list, Direction dir = Forward) : m_curr(dir == Forward ? list.getHead() : list.getTail()) {}
00265 
00267         operator bool() const
00268         {
00269             return m_curr != nullptr;
00270         }
00271 
00273         operator const DLink*() const
00274         {
00275             return m_curr;
00276         }
00277 
00279         const DLink*    operator ++ ()
00280         {
00281             return m_curr = m_curr->getNext();
00282         }
00283 
00285         const DLink*    operator -- ()
00286         {
00287             return m_curr = m_curr->getPrev();
00288         }
00289 
00290     private:
00291         const DLink*    m_curr;
00292     };
00293 
00294 private:
00295     DLink*  m_head;
00296     DLink*  m_tail;
00297 };
00298 
00299 } // end namespace Blast
00300 } // end namespace Nv
00301 
00302 
00303 #endif // #ifndef NVBLASTDLINK_H
Copyright © 2015-2017 NVIDIA Corporation, 2701 San Tomas Expressway, Santa Clara, CA 95050 U.S.A. All rights reserved. www.nvidia.com