yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
4c76b2759
master
1// slang-semantic-version.cpp 2#include "slang-semantic-version.h" 3 4#include "../core/slang-string-util.h" 5#include "slang-com-helper.h" 6 7namespace Slang 8{ 9 10// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! SemanticVersion !!!!!!!!!!!!!!!!!!!!!!!!!!!!! 11 12SlangResult SemanticVersion ::parse ( 13const UnownedStringSlice & value , 14char separatorChar , 15SemanticVersion & outVersion ) 16{ 17outVersion .reset (); 18 19UnownedStringSlice slices [3 ]; 20Index splitCount ; 21SLANG_RETURN_ON_FAIL (StringUtil ::split (value ,separatorChar ,3 ,slices ,splitCount )); 22if (splitCount <=0 ) 23 { 24return SLANG_FAIL ; 25 } 26 27Int ints [3 ]= {0 ,0 ,0 }; 28for (Index i = 0 ;i < splitCount ;i ++ ) 29 { 30SLANG_RETURN_ON_FAIL (StringUtil ::parseInt (slices [i ],ints [i ])); 31 32const Int max = (i == 2 ) ?0x7fffffff :0xffff ; 33if (ints [i ]< 0 || ints [i ]> max ) 34 { 35return SLANG_FAIL ; 36 } 37 } 38 39outVersion .m_major = uint16_t (ints [0 ]); 40outVersion .m_minor = uint16_t (ints [1 ]); 41outVersion .m_patch = uint32_t (ints [2 ]); 42 43return SLANG_OK ; 44} 45 46SlangResult SemanticVersion ::parse (const UnownedStringSlice & value ,SemanticVersion & outVersion ) 47{ 48return parse (value ,'.' ,outVersion ); 49} 50 51void SemanticVersion ::append (StringBuilder & buf )const 52{ 53buf <<Int32 (m_major ) <<"." <<Int32 (m_minor ); 54if (m_patch != 0 ) 55 { 56buf <<"." <<UInt32 (m_patch ); 57 } 58} 59 60/* static */ SemanticVersion SemanticVersion ::getEarliest (const ThisType * versions ,Count count ) 61{ 62if (count <=0 ) 63 { 64return SemanticVersion (); 65 } 66 67SemanticVersion bestVersion = versions [0 ]; 68for (const auto version :makeConstArrayView (versions + 1 ,count - 1 )) 69 { 70if (version < bestVersion ) 71 { 72bestVersion = version ; 73 } 74 } 75return bestVersion ; 76} 77 78/* static */ SemanticVersion SemanticVersion ::getLatest (const ThisType * versions ,Count count ) 79{ 80if (count <=0 ) 81 { 82return SemanticVersion (); 83 } 84 85SemanticVersion bestVersion = versions [0 ]; 86for (const auto version :makeConstArrayView (versions + 1 ,count - 1 )) 87 { 88if (version > bestVersion ) 89 { 90bestVersion = version ; 91 } 92 } 93return bestVersion ; 94} 95 96bool SemanticVersion ::isBackwardsCompatibleWith (const ThisType & otherVersion )const 97{ 98// Compatibility is not guaranteed across major revisions. 99// 100if (m_major != otherVersion .m_major ) 101return false; 102 103// Within a given major revision, a version with a higher 104// minor revision is backwards-compatible with one that 105// has a lower minor revision, but not vice-versa. 106// 107if (m_minor < otherVersion .m_minor ) 108return false; 109 110// If the major and minor revisions pass our check, then 111// we consider it a match. Note that this intentionally 112// doesn't check the path version at all. 113// 114return true; 115} 116 117 118// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! MatchSemanticVersion !!!!!!!!!!!!!!!!!!!!!!!!!!!!! 119 120/* static */ SemanticVersion MatchSemanticVersion ::findAnyBest ( 121const SemanticVersion * versions , 122Count count , 123const ThisType & matchVersion ) 124{ 125// If there aren't any we are done 126if (count <=0 ) 127 { 128return SemanticVersion (); 129 } 130 131// If there is only one it must be the best 132if (count == 1 ) 133 { 134return versions [0 ]; 135 } 136 137// Define a version range [start, end) 138SemanticVersion start ,end ; 139 140switch (matchVersion .m_kind ) 141 { 142case Kind ::Past : 143 { 144return SemanticVersion ::getEarliest (versions ,count ); 145 } 146case Kind ::Unknown : 147case Kind ::Future : 148 { 149// If it's unknown, we just get the latest 150return SemanticVersion ::getLatest (versions ,count ); 151 } 152case Kind ::Major : 153 { 154start = SemanticVersion (matchVersion .m_version .m_major ,0 ,0 ); 155end = SemanticVersion (matchVersion .m_version .m_major + 1 ,0 ,0 ); 156break ; 157 } 158case Kind ::MajorMinor : 159 { 160start = 161SemanticVersion (matchVersion .m_version .m_major ,matchVersion .m_version .m_minor ,0 ); 162end = SemanticVersion ( 163matchVersion .m_version .m_major , 164matchVersion .m_version .m_minor + 1 , 1650 ); 166break ; 167 } 168case Kind ::MajorMinorPatch : 169 { 170start = SemanticVersion (matchVersion .m_version ); 171end = SemanticVersion ( 172matchVersion .m_version .m_major , 173matchVersion .m_version .m_minor , 174matchVersion .m_version .m_patch + 1 ); 175break ; 176 } 177default : 178break ; 179 } 180 181List < SemanticVersion > sortedVersions ; 182sortedVersions .addRange (versions ,count ); 183 184// Sort into increasing values 185sortedVersions .sort ( 186 [& ](const SemanticVersion & a ,const SemanticVersion & b )-> bool {return a < b ; }); 187 188Index startIndex = 0 ; 189for (;startIndex < count && sortedVersions [startIndex ]< start ;++ startIndex ) 190 ; 191 192Index endIndex = startIndex ; 193for (;endIndex < count && sortedVersions [endIndex ]< end ;++ endIndex ) 194 ; 195 196// If we have a span of versions, get the last in the span 197if (startIndex < endIndex ) 198 { 199// Get the last one 200return sortedVersions [endIndex - 1 ]; 201 } 202 203// Get the next greatest if there is one 204if (endIndex < count ) 205 { 206return sortedVersions [endIndex ]; 207 } 208 209// Get the prior prior to the start 210if (startIndex > 0 ) 211 { 212return sortedVersions [startIndex - 1 ]; 213 } 214 215// All cases should be covered, but return the last one 216return sortedVersions [count - 1 ]; 217} 218 219void MatchSemanticVersion ::append (StringBuilder & buf )const 220{ 221switch (m_kind ) 222 { 223default : 224case Kind ::Unknown : 225buf <<"unknown" ; 226break ; 227case Kind ::Past : 228buf <<"past" ; 229break ; 230case Kind ::Future : 231buf <<"future" ; 232break ; 233case Kind ::Major : 234 { 235buf <<m_version .m_major ; 236break ; 237 } 238case Kind ::MajorMinor : 239 { 240buf <<m_version .m_major <<"." <<m_version .m_minor ; 241break ; 242 } 243case Kind ::MajorMinorPatch : 244 { 245m_version .append (buf ); 246break ; 247 } 248 } 249} 250 251}// namespace Slang