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_COMMAND_OPTIONS_H 2#define SLANG_CORE_COMMAND_OPTIONS_H 3 4#include "slang-basic.h" 5#include "slang-name-value.h" 6#include "slang-string-slice-pool.h" 7 8namespace Slang 9{ 10 11/* For convenience we encode within "names" flags. 12"-D..." means that -D *must* be followed by the value 13"-D?..." means that -D *can* be a prefix, or it might be followed with the arg 14*/ 15 16struct CommandOptions 17{ 18typedef uint32_t Flags ; 19 20typedef int32_t UserIndex ; 21enum class UserValue :UserIndex ; 22static const UserValue kInvalidUserValue = UserValue (0x80000000 ); 23 24enum class LookupKind :int32_t 25 { 26Category = -2 ,///< Lookup a category name 27Option = -1 ,///< Lookup an option name (all options use the same lookup index even if in 28///< different categories) 29Base = 0 ,///< Lookup via category index 30 }; 31 32/// A key type that uses the combination of the lookup kind and a name index. 33/// Maps to a target index that could be a category or an option index. 34struct NameKey 35 { 36typedef NameKey ThisType ; 37 38SLANG_FORCE_INLINE bool operator == (const ThisType & rhs )const 39 { 40return kind == rhs .kind && nameIndex == rhs .nameIndex ; 41 } 42SLANG_FORCE_INLINE bool operator != (const ThisType & rhs )const {return !(* this == rhs ); } 43HashCode getHashCode ()const 44 { 45return combineHash (Slang ::getHashCode (kind ),Slang ::getHashCode (nameIndex )); 46 } 47 48LookupKind kind ;///< The kind of lookup 49Index nameIndex ;///< The name index in the pool 50 }; 51 52enum class CategoryKind 53 { 54Option ,///< Command line option (like "-D") 55Value ,///< One of a set of values (such as an enum or some other kind of list of values) 56 }; 57 58struct ValuePair 59 { 60const char * name ; 61const char * description ; 62 }; 63 64struct Category 65 { 66UserValue userValue = kInvalidUserValue ; 67 68CategoryKind kind ; 69UnownedStringSlice name ; 70UnownedStringSlice description ; 71 72// Holds the span that defines all of the options associated with the category 73Index optionStartIndex = 0 ; 74Index optionEndIndex = 0 ; 75 }; 76 77struct Flag 78 { 79enum Enum :Flags 80 { 81CanPrefix = 0x1 ,/// Allows -Dfsggf or -D fdsfsd 82IsPrefix = 0x2 ,/// Is an option that can only be a prefix 83 }; 84 }; 85 86struct Option 87 { 88UnownedStringSlice names ;///< Comma delimited list of names, first name is the default 89UnownedStringSlice usage ;///< Describes usage, can be empty 90UnownedStringSlice description ;///< A description of usage 91 92UserValue userValue = kInvalidUserValue ; 93 94Index categoryIndex = -1 ;///< Category this option belongs to 95Flags flags = 0 ;///< Flags about this option 96 }; 97 98/// Get the first name 99UnownedStringSlice getFirstNameForOption (Index optionIndex ); 100/// Get the first name for the category 101UnownedStringSlice getFirstNameForCategory (Index categoryIndex ); 102 103/// Get a name key for an opton 104NameKey getNameKeyForOption (Index optionIndex ); 105/// Get a name key for a category 106NameKey getNameKeyForCategory (Index optionIndex ); 107 108/// Add a category 109Index addCategory ( 110CategoryKind kind , 111const char * name , 112const char * description , 113UserValue userValue = kInvalidUserValue ); 114/// Use an already known category. It's an error if the category isn't found 115void setCategory (const char * name ); 116 117void add ( 118const char * name , 119const char * usage , 120const char * description , 121UserValue userValue = kInvalidUserValue ); 122void add ( 123const UnownedStringSlice * names , 124Count namesCount , 125const char * usage , 126const char * description , 127UserValue userValue = kInvalidUserValue , 128Flags flags = 0 ); 129 130void addValue (const UnownedStringSlice & name ,UserValue userValue = kInvalidUserValue ); 131void addValue ( 132const UnownedStringSlice & name , 133const UnownedStringSlice & description , 134UserValue userValue = kInvalidUserValue ); 135void addValue ( 136const char * name , 137const char * description , 138UserValue userValue = kInvalidUserValue ); 139void addValue (const char * name ,UserValue userValue = kInvalidUserValue ); 140void addValue ( 141const UnownedStringSlice * names , 142Count namesCount , 143UserValue userValue = kInvalidUserValue ); 144 145/// Add values (without UserValue association) 146void addValues (const ValuePair * pairs ,Count pairsCount ); 147 148/// Add values 149void addValues (const ConstArrayView < NameValue >& values ); 150void addValues (const ConstArrayView < NamesValue >& values ); 151void addValues (const ConstArrayView < NamesDescriptionValue >& values ); 152 153/// Sometimes values are listed with *names* per value. This method will take into account the 154/// aliases 155void addValuesWithAliases (const ConstArrayView < NameValue >& values ); 156 157/// Get the target index based off the name and the kind 158Index findTargetIndexByName ( 159LookupKind kind , 160const UnownedStringSlice & name , 161NameKey * outNameKey = nullptr )const ; 162/// Given a kind and a user value lookup the target index 163Index findTargetIndexByUserValue (LookupKind kind ,UserValue userValue )const ; 164 165/// Finds the category by name or -1 if not found 166Index findCategoryByName (const UnownedStringSlice & name )const 167 { 168return findTargetIndexByName (LookupKind ::Category ,name ); 169 } 170/// Finds the option index by name or -1 if not found 171Index findOptionByName (const UnownedStringSlice & name )const 172 { 173return findTargetIndexByName (LookupKind ::Option ,name ); 174 } 175/// Find the option index of a value, using it's category index and the name 176Index findValueByName (Index categoryIndex ,const UnownedStringSlice & name )const 177 { 178return findTargetIndexByName (LookupKind (categoryIndex ),name ); 179 } 180 181/// Get the category index from a user value 182Index findCategoryByUserValue (UserValue userValue )const 183 { 184return findTargetIndexByUserValue (LookupKind ::Category ,userValue ); 185 } 186/// Can only get options 187Index findOptionByUserValue (UserValue userValue )const 188 { 189return findTargetIndexByUserValue (LookupKind ::Option ,userValue ); 190 } 191/// Get a value associated with a category 192Index findValueByUserValue (Index categoryIndex ,UserValue userValue )const 193 { 194return findTargetIndexByUserValue (LookupKind (categoryIndex ),userValue ); 195 } 196 197/// Given a category user value, find the associated name 198/// Returns -1 if not found 199Index findOptionByCategoryUserValue (UserValue categoryUserValue ,const UnownedStringSlice & name ) 200const ; 201 202/// Find a category by case insensitive name. Returns -1 if not found 203Index findCategoryByCaseInsensitiveName (const UnownedStringSlice & slice )const ; 204 205/// Given a category index returns all the options associated. 206ConstArrayView < Option > getOptionsForCategory (Index categoryIndex )const ; 207 208/// Get the categories 209const List < Category >& getCategories ()const {return m_categories ; } 210 211/// Get all the options 212const List < Option >& getOptions ()const {return m_options ; } 213 214/// Get the option at the specified index 215const Option & getOptionAt (Index index )const {return m_options [index ]; } 216 217/// Find all of the categories in the usage slice 218void findCategoryIndicesFromUsage ( 219const UnownedStringSlice & usageSlice , 220List < Index >& outCategories )const ; 221 222/// Splits usage into category slices 223void splitUsage (const UnownedStringSlice & usageSlice ,List < UnownedStringSlice >& outSlices ) 224const ; 225 226/// Get all the option names associated with a category index 227void getCategoryOptionNames (Index categoryIndex ,List < UnownedStringSlice >& outNames )const ; 228void appendCategoryOptionNames (Index categoryIndex ,List < UnownedStringSlice >& outNames )const ; 229 230/// Set up a lookup kind from a category index 231static LookupKind makeLookupKind (Index categoryIndex ) {return LookupKind (categoryIndex ); } 232 233/// Returns true, if all values from [start, end) are found for the kind 234bool hasContiguousUserValueRange (LookupKind kind ,UserValue start ,UserValue nonInclEnd )const ; 235 236/// Returns the number of options in the range 237Count getOptionCountInRange (Index categoryIndex ,UserValue start ,UserValue nonInclEnd )const ; 238Count getOptionCountInRange (LookupKind kind ,UserValue start ,UserValue nonInclEnd )const ; 239 240 241/// Ctor 242CommandOptions () 243 :m_pool (StringSlicePool ::Style ::Default ),m_arena (1024 * 2 ) 244 { 245 } 246 247protected : 248/// Returns name in the m_optionPool or -1 on error 249SlangResult _addOptionName (const UnownedStringSlice & name ,Flags flags ,Index targetIndex ); 250SlangResult _addValueName ( 251const UnownedStringSlice & name, 252Index categoryIndex, 253Index targetIndex); 254SlangResult _addName ( LookupKind kind, const UnownedStringSlice & name, Index targetIndex); 255 256SlangResult _addUserValue ( LookupKind kind, UserValue userValue, Index targetIndex); 257 258Index _addOption ( const UnownedStringSlice & name, const Option & inOption); 259Index _addOption ( const UnownedStringSlice * names, Count namesCount, const Option & option); 260 261Index _addValue ( const UnownedStringSlice & name, const Option & inOption); 262 263UnownedStringSlice _addString ( const char * text); 264UnownedStringSlice _addString ( const UnownedStringSlice & slice); 265 266Index _findTargetIndexByName ( 267LookupKind kind, 268const UnownedStringSlice & name, 269NameKey * outNameKey) const; 270 271struct UserValueKey 272{ 273typedef UserValueKey ThisType; 274 275SLANG_FORCE_INLINE bool operator == ( const ThisType & rhs ) const 276{ 277return kind == rhs . kind && userValue == rhs . userValue ; 278} 279SLANG_FORCE_INLINE bool operator != ( const ThisType & rhs) const { return !( * this == rhs); } 280HashCode getHashCode () const 281{ 282return combineHash( Slang :: getHashCode ( kind ), Slang :: getHashCode ( userValue )); 283} 284 285LookupKind kind; ///< The kind of lookup 286UserValue userValue; ///< The user value 287}; 288 289Index m_currentCategoryIndex = -1 ; 290 291List < Category > m_categories; 292 293// Holds a bit for all valid prefix sizes. Max prefix size is therefore 32 chars 294uint32_t m_prefixSizes = 0 ; 295 296List < Option > m_options; ///< All of the entries describing each of the options 297StringSlicePool m_pool; ///< Only holds options, and handle therefore matches up to m_entries 298Dictionary < NameKey, Index > m_nameMap; ///< Maps a name to an option index 299Dictionary < UserValueKey, Index > m_userValueMap; ///< Maps a user value (for a kind) to an index 300 301MemoryArena m_arena; ///< For other misc storage 302}; 303 304} // namespace Slang 305 306#endif