diff --git a/libs/shaderlib.h b/libs/shaderlib.h index 003f7a8c..4b2259d1 100644 --- a/libs/shaderlib.h +++ b/libs/shaderlib.h @@ -41,13 +41,7 @@ inline bool shader_equal_prefix( const char* string, const char* prefix ){ return shader_equal_n( string, prefix, string_length( prefix ) ); } -class shader_less_t -{ -public: - bool operator()( const CopiedString& shader, const CopiedString& other ) const { - return shader_less( shader.c_str(), other.c_str() ); - } -}; +using shader_less_t = StringLessNoCase; inline bool shader_valid( const char* shader ){ return string_is_ascii( shader ) diff --git a/libs/string/string.h b/libs/string/string.h index 9f65e3b6..9ceb3f67 100644 --- a/libs/string/string.h +++ b/libs/string/string.h @@ -52,6 +52,14 @@ inline int string_compare( const char* string, const char* other ){ return std::strcmp( string, other ); } +/// \brief Returns <0 if [\p string, \p string + \p n) is lexicographically less than [\p other, \p other + \p n). +/// Returns >0 if [\p string, \p string + \p n) is lexicographically greater than [\p other, \p other + \p n). +/// Returns 0 if [\p string, \p string + \p n) is lexicographically equal to [\p other, \p other + \p n). +/// O(n) +inline int string_compare_n( const char* string, const char* other, std::size_t n ){ + return std::strncmp( string, other, n ); +} + /// \brief Returns true if \p string is lexicographically equal to \p other. /// O(n) inline bool string_equal( const char* string, const char* other ){ @@ -61,7 +69,7 @@ inline bool string_equal( const char* string, const char* other ){ /// \brief Returns true if [\p string, \p string + \p n) is lexicographically equal to [\p other, \p other + \p n). /// O(n) inline bool string_equal_n( const char* string, const char* other, std::size_t n ){ - return std::strncmp( string, other, n ) == 0; + return string_compare_n( string, other, n ) == 0; } /// \brief Returns true if \p string is lexicographically less than \p other. @@ -608,6 +616,30 @@ public: /// \brief A non-mutable string which uses copy-by-reference for assignment of SmartString. typedef String< SmartBuffer< DefaultAllocator > > SmartString; + +template<> +struct std::less +{ + using is_transparent = void; + + bool operator()( const CopiedString& x, const CopiedString& y ) const { + return string_less( x.c_str(), y.c_str() ); + } + bool operator()( const CopiedString& x, const char *y ) const { + return string_less( x.c_str(), y ); + } + bool operator()( const char *x, const CopiedString& y ) const { + return string_less( x, y.c_str() ); + } + bool operator()( const CopiedString& string, const StringRange range ) const { + return string_compare_n( string.c_str(), range.data(), range.size() ) < 0; + } + bool operator()( const StringRange range, const CopiedString& string ) const { + return string_compare_n( string.c_str(), range.data(), range.size() ) > 0; + } +}; + + class StringEqualNoCase { public: @@ -618,9 +650,23 @@ public: struct StringLessNoCase { + using is_transparent = void; + bool operator()( const CopiedString& x, const CopiedString& y ) const { return string_less_nocase( x.c_str(), y.c_str() ); } + bool operator()( const CopiedString& x, const char *y ) const { + return string_less_nocase( x.c_str(), y ); + } + bool operator()( const char *x, const CopiedString& y ) const { + return string_less_nocase( x, y.c_str() ); + } + bool operator()( const CopiedString& string, const StringRange range ) const { + return string_compare_nocase_n( string.c_str(), range.data(), range.size() ) < 0; + } + bool operator()( const StringRange range, const CopiedString& string ) const { + return string_compare_nocase_n( string.c_str(), range.data(), range.size() ) > 0; + } }; struct RawStringEqual diff --git a/radiant/modelwindow.cpp b/radiant/modelwindow.cpp index 93c0935d..7f2879bb 100644 --- a/radiant/modelwindow.cpp +++ b/radiant/modelwindow.cpp @@ -1179,15 +1179,15 @@ public: }; -typedef std::set StringSetWithLambda; +using StringSetNoCase = std::set; class ModelPaths_ArchiveVisitor : public Archive::Visitor { - const StringSetWithLambda& m_modelExtensions; + const StringSetNoCase& m_modelExtensions; ModelFS& m_modelFS; public: const ModelFoldersMap& m_modelFoldersMap; - ModelPaths_ArchiveVisitor( const StringSetWithLambda& modelExtensions, ModelFS& modelFS, const ModelFoldersMap& modelFoldersMap ) + ModelPaths_ArchiveVisitor( const StringSetNoCase& modelExtensions, ModelFS& modelFS, const ModelFoldersMap& modelFoldersMap ) : m_modelExtensions( modelExtensions ), m_modelFS( modelFS ), m_modelFoldersMap( modelFoldersMap ){ } void visit( const char* name ) override { @@ -1218,9 +1218,7 @@ void ModelBrowser_constructTree(){ class : public IFileTypeList { public: - StringSetWithLambda m_modelExtensions{ []( const CopiedString& lhs, const CopiedString& rhs )->bool{ - return string_less_nocase( lhs.c_str(), rhs.c_str() ); - } }; + StringSetNoCase m_modelExtensions; void addType( const char* moduleName, filetype_t type ) override { m_modelExtensions.emplace( moduleName ); }