yum-mirror/slang

Making it easier to work with shaders

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

Theresa FoleyAdd a memory-mappable binary serialization format (#7222)ec7ab914f

master
2.7 KiB126 linesraw
1// slang-internally-linked-list.h
2#ifndef SLANG_INTERNALLY_LINKED_LIST_H
3#define SLANG_INTERNALLY_LINKED_LIST_H
4
5// This file provides support for the idiom of a linked
6// list of values where the "next" pointer is stored in
7// the values themselves (thus requiring no additional
8// allocation for list nodes, at the price of any given
9// value only being able to appear in a single list).
10
11#include "slang-basic.h"
12
13namespace Slang
14{
15
16/// A linked list where the elements are themselves the nodes.
17///
18/// The type parameter `T` should be a type that publicly
19/// inherits from `InternallyLinkedList<T>::Node`.
20///
21template<typename T>
22struct InternallyLinkedList
23{
24public:
25    struct Node
26    {
27    public:
28        Node() {}
29
30    private:
31        friend struct InternallyLinkedList<T>;
32        T* _next = nullptr;
33    };
34
35    struct Iterator
36    {
37    public:
38        Iterator() {}
39
40        Iterator(T* node)
41            : _node(node)
42        {
43        }
44
45        T* operator*() const { return _node; }
46
47        void operator++() { _node = static_cast<Node const*>(_node)->_next; }
48
49        bool operator!=(Iterator const& that) const { return _node != that._node; }
50
51    private:
52        T* _node = nullptr;
53    };
54
55    Iterator begin() { return Iterator(_first); }
56
57    Iterator end() { return Iterator(); }
58
59    T* getFirst() const { return _first; }
60
61    T* getLast() const { return _last; }
62
63    void add(T* element)
64    {
65        SLANG_ASSERT(element != nullptr);
66        if (!_last)
67        {
68            SLANG_ASSERT(_first == nullptr);
69
70            _first = element;
71            _last = element;
72        }
73        else
74        {
75            SLANG_ASSERT(_first != nullptr);
76
77            _last->_next = element;
78            _last = element;
79        }
80    }
81
82    void insertAfter(T* existingElement, T* newElement)
83    {
84        SLANG_ASSERT(existingElement != nullptr);
85        SLANG_ASSERT(newElement != nullptr);
86        if (existingElement == _last)
87        {
88            add(newElement);
89        }
90        else
91        {
92            newElement->_next = existingElement->_next;
93            existingElement->_next = newElement;
94        }
95    }
96
97    void append(InternallyLinkedList<T> const& other)
98    {
99        if (!other._first)
100        {
101        }
102        else if (!_last)
103        {
104            _first = other._first;
105            _last = other._last;
106        }
107        else
108        {
109            SLANG_ASSERT(_first != nullptr);
110
111            _last->_next = other._first;
112            _last = other._last;
113        }
114    }
115
116private:
117    T* _first = nullptr;
118    T* _last = nullptr;
119};
120
121template<typename T>
122using InternallyLinkedListNode = InternallyLinkedList<T>::Node;
123
124} // namespace Slang
125
126#endif