yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
f65d756bf
master
1#include "slang-string-slice-pool.h" 2 3namespace Slang 4{ 5 6/* static */ const StringSlicePool ::Handle StringSlicePool ::kNullHandle ; 7/* static */ const StringSlicePool ::Handle StringSlicePool ::kEmptyHandle ; 8 9/* static */ const Index StringSlicePool ::kDefaultHandlesCount ; 10 11StringSlicePool ::StringSlicePool (Style style ) 12 :m_style (style ),m_arena (1024 ) 13{ 14clear (); 15} 16 17StringSlicePool ::StringSlicePool (const ThisType & rhs ) 18 :m_style (rhs .m_style ),m_arena (1024 ) 19{ 20// Set with rhs 21_set (rhs ); 22} 23 24void StringSlicePool ::operator= (const ThisType & rhs ) 25{ 26if (& rhs != this ) 27 { 28_set (rhs ); 29 } 30} 31 32void StringSlicePool ::_set (const ThisType & rhs ) 33{ 34SLANG_ASSERT (this != & rhs ); 35m_style = rhs .m_style ; 36 37clear (); 38 39const Index startIndex = rhs .getFirstAddedIndex (); 40const Count count = rhs .m_slices .getCount (); 41 42if (count == 0 ) 43return ; 44 45// We need the same amount of slices 46m_slices .setCount (count ); 47 48// Work out the total size to store all slices including terminating 0 49// (which *isn't* part of the slice size) 50size_t totalSize = 0 ; 51 52for (Index i = startIndex ;i < count ;++ i ) 53 { 54const auto slice = rhs .m_slices [i ]; 55totalSize += slice .getLength ()+ 1 ; 56 } 57 58char * dst = (char * )m_arena .allocate (totalSize ); 59 60for (Index i = startIndex ;i < count ;++ i ) 61 { 62const auto srcSlice = rhs .m_slices [i ]; 63const auto sliceSize = srcSlice .getLength (); 64 65// Copy over the src slices contents 66 ::memcpy (dst ,srcSlice .begin (),sliceSize ); 67// Zero terminate 68dst [sliceSize ]= 0 ; 69 70const UnownedStringSlice dstSlice (dst ,sliceSize ); 71// Set the slice 72m_slices [i ]= dstSlice ; 73 74// Add to the map 75m_map .add (dstSlice ,Handle (i )); 76 77// Skip to next slices storage 78dst += sliceSize + 1 ; 79 } 80} 81 82bool StringSlicePool ::operator== (const ThisType & rhs )const 83{ 84if (this == & rhs ) 85 { 86return true; 87 } 88 89if (m_style != rhs .m_style ) 90 { 91return false; 92 } 93 94const auto count = m_slices .getCount (); 95 96if (count != rhs .m_slices .getCount ()) 97 { 98return false; 99 } 100 101for (Index i = 0 ;i < count ;++ i ) 102 { 103if (m_slices [i ]!= rhs .m_slices [i ]) 104 { 105return false; 106 } 107 } 108 109return true; 110} 111 112void StringSlicePool ::clear () 113{ 114m_map .clear (); 115m_arena .deallocateAll (); 116 117switch (m_style ) 118 { 119case Style ::Default : 120 { 121// Add the defaults 122m_slices .setCount (2 ); 123 124m_slices [0 ]= UnownedStringSlice ((const char * )nullptr , (const char * )nullptr ); 125m_slices [1 ]= UnownedStringSlice ::fromLiteral ("" ); 126 127// Add the empty entry 128m_map .add (m_slices [1 ],kEmptyHandle ); 129break ; 130 } 131case Style ::Empty : 132 { 133// There are no defaults 134m_slices .clear (); 135break ; 136 } 137 } 138} 139 140void StringSlicePool ::swapWith (ThisType & rhs ) 141{ 142Swap (m_style ,rhs .m_style ); 143m_slices .swapWith (rhs .m_slices ); 144m_map .swapWith (rhs .m_map ); 145m_arena .swapWith (rhs .m_arena ); 146} 147 148StringSlicePool ::Handle StringSlicePool ::add (const Slice & slice ) 149{ 150const Handle * handlePtr = m_map .tryGetValue (slice ); 151if (handlePtr ) 152 { 153return * handlePtr ; 154 } 155 156// Create a scoped copy 157UnownedStringSlice scopePath ( 158m_arena .allocateString (slice .begin (),slice .getLength ()), 159slice .getLength ()); 160 161const auto index = m_slices .getCount (); 162 163m_slices .add (scopePath ); 164m_map .add (scopePath ,Handle (index )); 165return Handle (index ); 166} 167 168bool StringSlicePool ::findOrAdd (const Slice & slice ,Handle & outHandle ) 169{ 170const Handle * handlePtr = m_map .tryGetValue (slice ); 171if (handlePtr ) 172 { 173outHandle = * handlePtr ; 174return true; 175 } 176 177// Need to add. 178 179// Make a copy stored in the arena 180UnownedStringSlice scopeSlice ( 181m_arena .allocateString (slice .begin (),slice .getLength ()), 182slice .getLength ()); 183 184// Add using the arenas copy 185Handle newHandle = Handle (m_slices .getCount ()); 186m_map .add (scopeSlice ,newHandle ); 187 188// Add to slices list 189m_slices .add (scopeSlice ); 190outHandle = newHandle ; 191return false; 192} 193 194StringSlicePool ::Handle StringSlicePool ::add (StringRepresentation * stringRep ) 195{ 196if (stringRep == nullptr && m_style == Style ::Default ) 197 { 198return kNullHandle ; 199 } 200return add (StringRepresentation ::asSlice (stringRep )); 201} 202 203StringSlicePool ::Handle StringSlicePool ::add (const char * chars ) 204{ 205switch (m_style ) 206 { 207case Style ::Default : 208 { 209if (!chars ) 210 { 211return kNullHandle ; 212 } 213if (chars [0 ]== 0 ) 214 { 215return kEmptyHandle ; 216 } 217break ; 218 } 219case Style ::Empty : 220 { 221if (chars == nullptr ) 222 { 223SLANG_ASSERT (!"Empty style doesn't support nullptr" ); 224// Return an invalid handle 225return Handle (~HandleIntegral (0 )); 226 } 227 } 228 } 229 230return add (UnownedStringSlice (chars )); 231} 232 233Index StringSlicePool ::findIndex (const Slice & slice )const 234{ 235const Handle * handlePtr = m_map .tryGetValue (slice ); 236return handlePtr ?Index (* handlePtr ) :-1 ; 237} 238 239ConstArrayView < UnownedStringSlice > StringSlicePool ::getAdded ()const 240{ 241const Index firstIndex = getFirstAddedIndex (); 242return makeConstArrayView (m_slices .getBuffer ()+ firstIndex ,m_slices .getCount ()- firstIndex ); 243} 244 245}// namespace Slang