yum-mirror/slang

Making it easier to work with shaders

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

Ellie Hermaszewskaformatf65d756bf

master
4.5 KiB138 linesraw
1#ifndef SLANG_CORE_STRING_SLICE_POOL_H
2#define SLANG_CORE_STRING_SLICE_POOL_H
3
4#include "slang-array-view.h"
5#include "slang-dictionary.h"
6#include "slang-list.h"
7#include "slang-memory-arena.h"
8#include "slang-string.h"
9
10namespace Slang
11{
12
13/* Holds a unique set of slices.
14
15Note that all slices (except kNullHandle) are stored with terminating zeros.
16
17The default handles kNullHandle, kEmptyHandle can only be used on a StringSlicePool
18initialized with the Style::Default. Not doing so will return an undefined result.
19
20TODO(JS):
21An argument could be made to make different classes, perhaps deriving from a base class
22that exhibited the two behaviors. That doing so would make the default handles defined
23for that class for example.
24
25This is a little awkward in practice, because behavior of some methods need to change
26(like adding a c string with nullptr, or clearing, as well as some other perhaps less necessary
27optimizations). This could be achieved via virtual functions, but this all seems overkill.
28*/
29class StringSlicePool
30{
31public:
32    typedef StringSlicePool ThisType;
33    typedef uint32_t HandleIntegral;
34
35    enum class Style
36    {
37        Default, ///< Default style - has default handles (like kNullHandle and kEmptyHandle)
38        Empty,   ///< Empty style - has no handles by default. Using default handles will likely
39                 ///< produce the wrong result.
40    };
41
42    enum class Handle : HandleIntegral;
43    typedef UnownedStringSlice Slice;
44
45    /// The following default handles *only* apply if constructed with the Style::Default
46
47    /// Handle of 0 is null. If accessed will be returned as the empty string with nullptr the chars
48    static const Handle kNullHandle = Handle(0);
49    /// Handle of 1 is the empty string.
50    static const Handle kEmptyHandle = Handle(1);
51
52    static const Index kDefaultHandlesCount = 2;
53
54    /// Returns the index of a slice, if contained, or -1 if not found
55    Index findIndex(const Slice& slice) const;
56
57    /// True if has the slice
58    bool has(const Slice& slice) { return findIndex(slice) >= 0; }
59    /// Add a slice
60    Handle add(const Slice& slice);
61    /// Add from a string
62    Handle add(const char* chars);
63    /// Add a StringRepresentation
64    Handle add(StringRepresentation* string);
65    /// Add a string
66    Handle add(const String& string) { return add(string.getUnownedSlice()); }
67
68    /// Add and get the result as a slice
69    Slice addAndGetSlice(const Slice& slice) { return getSlice(add(slice)); }
70    Slice addAndGetSlice(const char* chars) { return getSlice(add(chars)); }
71    Slice addAndGetSlice(const String& string) { return getSlice(add(string)); }
72
73    /// Returns true if found
74    bool findOrAdd(const Slice& slice, Handle& outHandle);
75
76    /// Empty contents
77    void clear();
78
79    /// Get the slice from the handle
80    const UnownedStringSlice& getSlice(Handle handle) const { return m_slices[UInt(handle)]; }
81
82    /// Get all the slices
83    const List<UnownedStringSlice>& getSlices() const { return m_slices; }
84
85    /// Get the number of slices
86    Index getSlicesCount() const { return m_slices.getCount(); }
87
88    /// Returns true if the handle is a default one. Only meaningful on a Style::Default.
89    bool isDefaultHandle(Handle handle) const
90    {
91        SLANG_ASSERT(
92            m_style == Style::Default &&
93            // TODO(C++20), use bit_cast here
94            HandleIntegral(handle) <= HandleIntegral(std::numeric_limits<Index>::max()));
95        return Index(handle) < kDefaultHandlesCount;
96    }
97
98    /// Convert a handle to and index. (A handle is just an index!)
99    static Index asIndex(Handle handle) { return Index(handle); }
100
101    /// Get the style of the pool
102    Style getStyle() const { return m_style; }
103
104    /// Get all the added slices (does not have default slices, if there are any)
105    ConstArrayView<UnownedStringSlice> getAdded() const;
106
107    /// Get the index of the first added handle
108    Index getFirstAddedIndex() const
109    {
110        return m_style == Style::Default ? kDefaultHandlesCount : 0;
111    }
112
113    /// Swap this with rhs
114    void swapWith(ThisType& rhs);
115
116    /// True if the pools are identical. Same style, same slices in the same order.
117    bool operator==(const ThisType& rhs) const;
118
119    /// Copy ctor
120    StringSlicePool(const ThisType& rhs);
121    /// Assignment
122    void operator=(const ThisType& rhs);
123
124    /// Ctor
125    explicit StringSlicePool(Style style);
126
127protected:
128    void _set(const ThisType& rhs);
129
130    Style m_style;
131    List<UnownedStringSlice> m_slices;
132    Dictionary<UnownedStringSlice, Handle> m_map;
133    MemoryArena m_arena;
134};
135
136} // namespace Slang
137
138#endif // SLANG_STRING_SLICE_POOL_H