yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
f65d756bf
master
1#ifndef SLANG_CORE_LINKED_LIST_H 2#define SLANG_CORE_LINKED_LIST_H 3 4#include "slang-allocator.h" 5#include "slang-list.h" 6#include "slang.h" 7 8#include <type_traits> 9 10namespace Slang 11{ 12template < typename T > 13class LinkedList ; 14 15template < typename T > 16class LinkedNode 17{ 18template < typename T1 > 19friend class LinkedList ; 20 21private : 22LinkedNode < T >* prev = nullptr ; 23LinkedNode < T >* next = nullptr ; 24LinkedList < T >* list ; 25 26public : 27T value ; 28LinkedNode (LinkedList < T >* lnk ) 29 :list (lnk ){}; 30LinkedNode < T >* getPrevious () {return prev ; }; 31LinkedNode < T >* getNext () {return next ; }; 32const LinkedNode < T >* getNext ()const {return next ; }; 33LinkedNode < T >* insertAfter (const T & nData ) 34 { 35LinkedNode < T >* n = new LinkedNode < T > (list ); 36n -> value = nData ; 37n -> prev = this ; 38n -> next = this -> next ; 39LinkedNode < T >* npp = n -> next ; 40if (npp ) 41 { 42npp -> prev = n ; 43 } 44next = n ; 45if (!n -> next ) 46list -> tail = n ; 47list -> count ++ ; 48return n ; 49 }; 50LinkedNode < T >* insertBefore (const T & nData ) 51 { 52LinkedNode < T >* n = new LinkedNode < T > (list ); 53n -> value = nData ; 54n -> prev = prev ; 55n -> next = this ; 56prev = n ; 57LinkedNode < T >* npp = n -> prev ; 58if (npp ) 59npp -> next = n ; 60if (!n -> prev ) 61list -> head = n ; 62list -> count ++ ; 63return n ; 64 }; 65void removeAndDelete () 66 { 67if (prev ) 68prev -> next = next ; 69if (next ) 70next -> prev = prev ; 71list -> count -- ; 72if (list -> head == this ) 73 { 74list -> head = next ; 75 } 76if (list -> tail == this ) 77 { 78list -> tail = prev ; 79 } 80delete this ; 81 } 82}; 83 84template < typename T > 85class LinkedList 86{ 87template < typename T1 > 88friend class LinkedNode ; 89 90private : 91LinkedNode < T >* head ,* tail ; 92int count ; 93 94public : 95template < bool Const > 96class GenIterator 97 { 98public : 99using Node = std ::conditional_t < Const ,const LinkedNode < T > ,LinkedNode < T >>; 100Node * current ,* next ; 101void setCurrent (Node * cur ) 102 { 103current = cur ; 104if (current ) 105next = current -> getNext (); 106else 107next = nullptr ; 108 } 109GenIterator () {current = next = nullptr ; } 110GenIterator (Node * cur ) {setCurrent (cur ); } 111std ::conditional_t < Const ,const T & ,T &> operator * ()const {return current -> value ; } 112GenIterator & operator ++ () 113 { 114setCurrent (next ); 115return * this ; 116 } 117GenIterator operator ++ (int ) 118 { 119GenIterator rs = * this ; 120setCurrent (next ); 121return rs ; 122 } 123bool operator != (const GenIterator & iter )const {return current != iter .current ; } 124bool operator == (const GenIterator & iter )const {return current == iter .current ; } 125 }; 126 127using Iterator = GenIterator < false> ; 128Iterator begin () {return Iterator (head ); } 129Iterator end () {return Iterator (0 ); } 130 131using ConstIterator = GenIterator < true> ; 132ConstIterator begin ()const {return ConstIterator (head ); } 133ConstIterator end ()const {return ConstIterator (0 ); } 134 135public : 136LinkedList () 137 :head (0 ),tail (0 ),count (0 ) 138 { 139 } 140 ~LinkedList () {clear (); } 141LinkedList (const LinkedList < T >& link ) 142 :head (0 ),tail (0 ),count (0 ) 143 { 144this -> operator = (link ); 145 } 146LinkedList (LinkedList < T >&& link ) 147 :head (0 ),tail (0 ),count (0 ) 148 { 149this -> operator = (_Move (link )); 150 } 151LinkedList < T >& operator = (LinkedList < T >&& link ) 152 { 153if (head != 0 ) 154clear (); 155head = link .head ; 156tail = link .tail ; 157count = link .count ; 158link .head = 0 ; 159link .tail = 0 ; 160link .count = 0 ; 161for (autonode = head ;node ;node = node -> getNext ()) 162node -> list = this ; 163return * this ; 164 } 165LinkedList < T >& operator = (const LinkedList < T >& link ) 166 { 167if (head != nullptr ) 168clear (); 169 autop = link. head ; 170while (p) 171{ 172addLast (p -> value ); 173p = p -> getNext (); 174} 175return * this; 176} 177template < typename IteratorFunc > 178void forEach( const IteratorFunc & f) 179{ 180auto p = head; 181while (p) 182{ 183f (p -> value ); 184p = p -> getNext (); 185} 186} 187LinkedNode < T >* getNode (int x) 188{ 189LinkedNode < T >* pCur = head; 190for ( int i = 0 ; i < x; i ++ ) 191{ 192if (pCur) 193pCur = pCur -> next ; 194else 195SLANG_UNEXPECTED ( "Index out of range" ); 196} 197return pCur; 198}; 199LinkedNode < T >* find (const T & fData) 200{ 201for (LinkedNode < T >* pCur = head; pCur; pCur = pCur -> next ) 202{ 203if (pCur -> value == fData) 204return pCur; 205} 206return nullptr ; 207}; 208LinkedNode < T >* getFirstNode () const { return head; }; 209T & getFirst () const 210{ 211if (!head) 212SLANG_UNEXPECTED ( "LinkedList: index out of range." ); 213return head -> value ; 214} 215T & getLast () const 216{ 217if (!tail) 218SLANG_UNEXPECTED ( "LinkedList: index out of range." ); 219return tail -> value ; 220} 221LinkedNode < T >* getLastNode () const { return tail; }; 222LinkedNode < T >* addLast (const T & nData) 223{ 224LinkedNode < T >* n = new LinkedNode < T > (this); 225n -> value = nData; 226n -> prev = tail; 227if (tail) 228tail -> next = n; 229n -> next = 0 ; 230tail = n; 231if (!head) 232head = n; 233count ++ ; 234return n; 235}; 236// Insert a blank node 237LinkedNode < T >* addLast () 238{ 239LinkedNode < T >* n = new LinkedNode < T > (this); 240n -> prev = tail; 241if (tail) 242tail -> next = n; 243n -> next = 0 ; 244tail = n; 245if (!head) 246head = n; 247count ++ ; 248return n; 249}; 250LinkedNode < T >* addFirst (const T & nData) 251{ 252LinkedNode < T >* n = new LinkedNode < T > (this); 253n -> value = nData; 254addFirst (n); 255count ++ ; 256return n; 257}; 258void addFirst ( LinkedNode < T >* n) 259{ 260n -> prev = 0 ; 261n -> next = head; 262if (head) 263head -> prev = n; 264head = n; 265if (!tail) 266tail = n; 267} 268void removeFromList ( LinkedNode < T >* n) 269{ 270LinkedNode < T >* n1, * n2 = 0 ; 271n1 = n -> prev ; 272n2 = n -> next ; 273if (n1) 274n1 -> next = n2; 275else 276head = n2; 277if (n2) 278n2 -> prev = n1; 279else 280tail = n1; 281n -> prev = nullptr ; 282n -> next = nullptr ; 283} 284void removeAndDelete ( LinkedNode < T >* n, int Count = 1 ) 285{ 286LinkedNode < T >* cur, * next; 287cur = n; 288int numDeleted = 0 ; 289for ( int i = 0 ; i < Count; i ++ ) 290{ 291next = cur -> next ; 292removeFromList (cur); 293delete cur; 294cur = next; 295numDeleted ++ ; 296if (cur == 0 ) 297break ; 298} 299count -= numDeleted; 300} 301void clear () 302{ 303for (LinkedNode < T >* n = head; n;) 304{ 305LinkedNode < T >* tmp = n -> next ; 306delete n; 307n = tmp; 308} 309head = 0 ; 310tail = 0 ; 311count = 0 ; 312} 313List < T > toList () const 314{ 315List < T > rs; 316rs. Reserve (count); 317for (auto & item : * this) 318{ 319rs. add ( item ); 320} 321return rs; 322} 323int getCount () const { return count; } 324}; 325} // namespace Slang 326#endif