yum-mirror/slang

Making it easier to work with shaders

git clone https://git.yummers.dev/yum-mirror/slang

Ellie Hermaszewskaformatf65d756bf

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