diff options
author | Brad King <brad.king@kitware.com> | 2023-07-19 14:39:46 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2023-07-19 14:40:02 (GMT) |
commit | e92156614280bece5452c85865f41d44082b1026 (patch) | |
tree | 6865102f51cc985b450af135350acc21503a86fb | |
parent | a594748cdf61146279cfd88f6c21e340e85af8c1 (diff) | |
parent | 945b9b8132e9d9eead61e2874bc0e00e9ae23270 (diff) | |
download | CMake-e92156614280bece5452c85865f41d44082b1026.zip CMake-e92156614280bece5452c85865f41d44082b1026.tar.gz CMake-e92156614280bece5452c85865f41d44082b1026.tar.bz2 |
Merge topic 'cmCMakePath-SunPro-sparc-workaround'
945b9b8132 cmCMakePath: workarounds for Sunpro/sparc compiler
Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: buildbot <buildbot@kitware.com>
Acked-by: Robert Maynard <robertjmaynard@gmail.com>
Merge-request: !8633
-rw-r--r-- | Source/cmCMakePath.cxx | 2 | ||||
-rw-r--r-- | Source/cmCMakePath.h | 213 | ||||
-rw-r--r-- | Tests/CMakeLib/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Tests/CMakeLib/testCMakePath.cxx | 441 |
4 files changed, 650 insertions, 7 deletions
diff --git a/Source/cmCMakePath.cxx b/Source/cmCMakePath.cxx index 73321c6..5080f58 100644 --- a/Source/cmCMakePath.cxx +++ b/Source/cmCMakePath.cxx @@ -15,6 +15,8 @@ #include <cm/string_view> #if defined(_WIN32) +# include <cmext/string_view> + # include "cmStringAlgorithms.h" #endif diff --git a/Source/cmCMakePath.h b/Source/cmCMakePath.h index 15aa30c..a42ac98 100644 --- a/Source/cmCMakePath.h +++ b/Source/cmCMakePath.h @@ -12,7 +12,10 @@ #include <cm/filesystem> #include <cm/string_view> #include <cm/type_traits> -#include <cmext/string_view> + +namespace cm { +class static_string_view; +} namespace detail { #if defined(__SUNPRO_CC) && defined(__sparc) @@ -123,11 +126,29 @@ public: : Path(FormatPath(source, fmt)) { } + cmCMakePath(const char* source, format fmt = generic_format) noexcept + : Path(FormatPath(cm::string_view{ source }, fmt)) + { + } +#if defined(__SUNPRO_CC) && defined(__sparc) + // Oracle DeveloperStudio C++ compiler on Solaris/Sparc is confused when + // standard methods and templates use the same name. The template is selected + // rather than the standard one regardless the arguments of the method. + cmCMakePath(const std::string& source, format fmt = generic_format) + : Path(FormatPath(source, fmt)) + { + } + cmCMakePath(std::string&& source, format fmt = generic_format) + : Path(FormatPath(std::move(source), fmt)) + { + } +#else template <typename Source, typename = enable_if_move_pathable<Source>> cmCMakePath(Source source, format fmt = generic_format) : Path(FormatPath(std::move(source), fmt)) { } +#endif template <typename Source, typename = enable_if_move_pathable<Source>> cmCMakePath& Assign(Source&& source) @@ -156,6 +177,41 @@ public: } return *this; } +#if defined(__SUNPRO_CC) && defined(__sparc) + // Oracle DeveloperStudio C++ compiler on Solaris/Sparc is confused when + // standard methods and templates use the same name. The template is selected + // rather than the standard one regardless the arguments of the method. + cmCMakePath& operator=(cm::filesystem::path&& source) + { + this->Assign(std::forward<cm::filesystem::path>(source)); + return *this; + } + cmCMakePath& operator=(std::string&& source) + { + this->Assign(std::forward<std::string>(source)); + return *this; + } + cmCMakePath& operator=(const cm::filesystem::path& source) + { + this->Assign(source); + return *this; + } + cmCMakePath& operator=(const std::string& source) + { + this->Assign(source); + return *this; + } + cmCMakePath& operator=(const cm::string_view source) + { + this->Assign(source); + return *this; + } + cmCMakePath& operator=(const char* source) + { + this->Assign(cm::string_view{ source }); + return *this; + } +#else template <typename Source, typename = enable_if_move_pathable<Source>> cmCMakePath& operator=(Source&& source) { @@ -168,6 +224,7 @@ public: this->Assign(source); return *this; } +#endif // Concatenation cmCMakePath& Append(const cmCMakePath& path) @@ -182,12 +239,29 @@ public: this->Path = this->Path.generic_string(); return *this; } - +#if defined(__SUNPRO_CC) && defined(__sparc) + // Oracle DeveloperStudio C++ compiler on Solaris/Sparc is confused when + // standard methods and templates use the same name. The template is selected + // rather than the standard one regardless the arguments of the method. + cmCMakePath& Append(const std::string& source) + { + return this->Append(cm::filesystem::path(source)); + } + cmCMakePath& Append(cm::string_view source) + { + return this->Append(cm::filesystem::path(source)); + } + cmCMakePath& Append(const char* source) + { + return this->Append(cm::filesystem::path(cm::string_view{ source })); + } +#else template <typename Source, typename = enable_if_pathable<Source>> cmCMakePath& Append(const Source& source) { return this->Append(cm::filesystem::path(source)); } +#endif cmCMakePath& operator/=(const cmCMakePath& path) { @@ -204,17 +278,38 @@ public: this->Path += path.Path; return *this; } - cmCMakePath& Concat(cm::static_string_view source) + cmCMakePath& Concat(cm::string_view source) { - this->Path.concat(std::string(source)); + this->Path.operator+=(std::string(source)); return *this; } +#if defined(__SUNPRO_CC) && defined(__sparc) + // Oracle DeveloperStudio C++ compiler on Solaris/Sparc is confused when + // standard methods and templates use the same name. The template is selected + // rather than the standard one regardless the arguments of the method. + cmCMakePath& Concat(const cm::filesystem::path& source) + { + this->Path.operator+=(source); + return *this; + } + cmCMakePath& Concat(const std::string& source) + { + this->Path.operator+=(source); + return *this; + } + cmCMakePath& Concat(const char* source) + { + this->Path.operator+=(source); + return *this; + } +#else template <typename Source, typename = enable_if_pathable<Source>> cmCMakePath& Concat(const Source& source) { - this->Path.concat(source); + this->Path.operator+=(source); return *this; } +#endif cmCMakePath& operator+=(const cmCMakePath& path) { @@ -242,6 +337,32 @@ public: } return *this; } +#if defined(__SUNPRO_CC) && defined(__sparc) + // Oracle DeveloperStudio C++ compiler on Solaris/Sparc is confused when + // standard methods and templates use the same name. The template is selected + // rather than the standard one regardless the arguments of the method. + cmCMakePath& ReplaceFileName(const cm::filesystem::path& filename) + { + if (this->Path.has_filename()) { + this->Path.replace_filename(filename); + } + return *this; + } + cmCMakePath& ReplaceFileName(const std::string& filename) + { + if (this->Path.has_filename()) { + this->Path.replace_filename(filename); + } + return *this; + } + cmCMakePath& ReplaceFileName(cm::string_view filename) + { + if (this->Path.has_filename()) { + this->Path.replace_filename(filename); + } + return *this; + } +#else template <typename Source, typename = enable_if_pathable<Source>> cmCMakePath& ReplaceFileName(const Source& filename) { @@ -250,18 +371,40 @@ public: } return *this; } +#endif cmCMakePath& ReplaceExtension(const cmCMakePath& extension = cmCMakePath()) { this->Path.replace_extension(extension.Path); return *this; } +#if defined(__SUNPRO_CC) && defined(__sparc) + // Oracle DeveloperStudio C++ compiler on Solaris/Sparc is confused when + // standard methods and templates use the same name. The template is selected + // rather than the standard one regardless the arguments of the method. + cmCMakePath& ReplaceExtension(const cm::filesystem::path& extension) + { + this->Path.replace_extension(extension); + return *this; + } + cmCMakePath& ReplaceExtension(const std::string& extension) + { + this->Path.replace_extension(extension); + return *this; + } + cmCMakePath& ReplaceExtension(const cm::string_view extension) + { + this->Path.replace_extension(extension); + return *this; + } +#else template <typename Source, typename = enable_if_pathable<Source>> cmCMakePath& ReplaceExtension(const Source& extension) { this->Path.replace_extension(extension); return *this; } +#endif cmCMakePath& ReplaceWideExtension( const cmCMakePath& extension = cmCMakePath()) @@ -269,11 +412,26 @@ public: return this->ReplaceWideExtension( static_cast<cm::string_view>(extension.Path.string())); } + cmCMakePath& ReplaceWideExtension(const cm::filesystem::path& extension) + { + return this->ReplaceWideExtension( + static_cast<cm::string_view>(extension.string())); + } +#if defined(__SUNPRO_CC) && defined(__sparc) + // Oracle DeveloperStudio C++ compiler on Solaris/Sparc is confused when + // standard methods and templates use the same name. The template is selected + // rather than the standard one regardless the arguments of the method. + cmCMakePath& ReplaceWideExtension(const std::string& extension) + { + return this->ReplaceWideExtension(cm::string_view{ extension }); + } +#else template <typename Source, typename = enable_if_pathable<Source>> cmCMakePath& ReplaceWideExtension(const Source& extension) { - return this->ReplaceWideExtension(cm::string_view(extension)); + return this->ReplaceWideExtension(extension); } +#endif cmCMakePath& ReplaceWideExtension(cm::string_view extension); cmCMakePath& RemoveExtension() @@ -355,12 +513,25 @@ public: // Windows) so convert back to '/' return path.generic_string(); } +#if defined(__SUNPRO_CC) && defined(__sparc) + // Oracle DeveloperStudio C++ compiler on Solaris/Sparc is confused when + // standard methods and templates use the same name. The template is selected + // rather than the standard one regardless the arguments of the method. + cmCMakePath Relative(const std::string& base) const + { + return this->Relative(cm::filesystem::path(base)); + } + cmCMakePath Relative(cm::string_view base) const + { + return this->Relative(cm::filesystem::path(base)); + } +#else template <typename Source, typename = enable_if_pathable<Source>> cmCMakePath Relative(const Source& base) const { return this->Relative(cm::filesystem::path(base)); } - +#endif cmCMakePath Proximate(const cmCMakePath& base) const { return this->Proximate(base.Path); @@ -372,21 +543,49 @@ public: // Windows) so convert back to '/' return path.generic_string(); } +#if defined(__SUNPRO_CC) && defined(__sparc) + // Oracle DeveloperStudio C++ compiler on Solaris/Sparc is confused when + // standard methods and templates use the same name. The template is selected + // rather than the standard one regardless the arguments of the method. + cmCMakePath Proximate(const std::string& base) const + { + return this->Proximate(cm::filesystem::path(base)); + } + cmCMakePath Proximate(cm::string_view base) const + { + return this->Proximate(cm::filesystem::path(base)); + } +#else template <typename Source, typename = enable_if_pathable<Source>> cmCMakePath Proximate(const Source& base) const { return this->Proximate(cm::filesystem::path(base)); } +#endif cmCMakePath Absolute(const cmCMakePath& base) const { return this->Absolute(base.Path); } +#if defined(__SUNPRO_CC) && defined(__sparc) + // Oracle DeveloperStudio C++ compiler on Solaris/Sparc is confused when + // standard methods and templates use the same name. The template is selected + // rather than the standard one regardless the arguments of the method. + cmCMakePath Absolute(const std::string& base) const + { + return this->Absolute(cm::filesystem::path(base)); + } + cmCMakePath Absolute(cm::string_view base) const + { + return this->Absolute(cm::filesystem::path(base)); + } +#else template <typename Source, typename = enable_if_pathable<Source>> cmCMakePath Absolute(const Source& base) const { return this->Absolute(cm::filesystem::path(base)); } +#endif cmCMakePath Absolute(const cm::filesystem::path& base) const; // Comparison diff --git a/Tests/CMakeLib/CMakeLists.txt b/Tests/CMakeLib/CMakeLists.txt index 8ce8f67..4454f49 100644 --- a/Tests/CMakeLib/CMakeLists.txt +++ b/Tests/CMakeLib/CMakeLists.txt @@ -31,6 +31,7 @@ set(CMakeLib_TESTS testCMExtAlgorithm.cxx testCMExtEnumSet.cxx testList.cxx + testCMakePath.cxx ) if(CMake_ENABLE_DEBUGGER) list(APPEND CMakeLib_TESTS diff --git a/Tests/CMakeLib/testCMakePath.cxx b/Tests/CMakeLib/testCMakePath.cxx new file mode 100644 index 0000000..aa17e50 --- /dev/null +++ b/Tests/CMakeLib/testCMakePath.cxx @@ -0,0 +1,441 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#include "cmConfigure.h" // IWYU pragma: keep + +#include <iostream> +#include <string> +#include <utility> + +#include <cm/string_view> +#include <cmext/string_view> + +#include "cmCMakePath.h" + +namespace { + +void checkResult(bool success) +{ + if (!success) { + std::cout << " => failed"; + } + std::cout << std::endl; +} + +bool testConstructors() +{ + std::cout << "testConstructors()"; + + bool result = true; + + { + cmCMakePath path; + if (!path.String().empty() || path != cmCMakePath{}) { + result = false; + } + } + { + cmCMakePath path{ "aa/bb" }; + if (path.String() != "aa/bb") { + result = false; + } + } + { + std::string s{ "aa/bb" }; + cmCMakePath path{ s }; + if (path.String() != "aa/bb") { + result = false; + } + } + { + cmCMakePath path{ "aa/bb"_s }; + if (path.String() != "aa/bb") { + result = false; + } + } + { + cmCMakePath path1{ "aa/bb" }; + cmCMakePath path2("aa/bb"_s); + + if (path1 != path2) { + result = false; + } + if (path1.String() != "aa/bb") { + result = false; + } + if (path1.String() != path2.String()) { + result = false; + } + } + { + cmCMakePath path1{ "aa/bb" }; + cmCMakePath path2{ path1 }; + + if (path1 != path2) { + result = false; + } + if (path1.String() != "aa/bb") { + result = false; + } + if (path1.String() != path2.String()) { + result = false; + } + } + + checkResult(result); + + return result; +} + +bool testAssign() +{ + std::cout << "testAssign()"; + + bool result = true; + + { + cmCMakePath path1{ "aa/bb" }; + cmCMakePath path2{ "cc/dd" }; + + path2 = path1; + if (path1 != path2) { + result = false; + } + if (path1.String() != "aa/bb") { + result = false; + } + if (path1.String() != path2.String()) { + result = false; + } + } + { + cmCMakePath path1{ "aa/bb" }; + cmCMakePath path2{ "cc/dd" }; + + path2 = std::move(path1); + if (path2.String() != "aa/bb") { + result = false; + } + } + { + std::string path1{ "aa/bb" }; + cmCMakePath path2{ "cc/dd" }; + + path2 = path1; + if (path2.String() != "aa/bb") { + result = false; + } + } + { + std::string path1{ "aa/bb" }; + cmCMakePath path2{ "cc/dd" }; + + path2 = std::move(path1); + if (path2.String() != "aa/bb") { + result = false; + } + } + { + cm::string_view path1{ "aa/bb" }; + cmCMakePath path2{ "cc/dd" }; + + path2 = path1; + if (path2.String() != "aa/bb") { + result = false; + } + } + { + char path1[] = "aa/bb"; + cmCMakePath path2{ "cc/dd" }; + + path2 = path1; + if (path2.String() != "aa/bb") { + result = false; + } + } + { + std::string path1{ "aa/bb" }; + cmCMakePath path2{ "cc/dd" }; + + path2.Assign(path1); + if (path2.String() != path1) { + result = false; + } + } + { + std::string path1{ "aa/bb" }; + cmCMakePath path2{ "cc/dd" }; + + path2.Assign(std::move(path1)); + if (path2.String() != "aa/bb") { + result = false; + } + } + { + cm::string_view path1{ "aa/bb" }; + cmCMakePath path2{ "cc/dd" }; + + path2.Assign(path1); + if (path2.String() != path1) { + result = false; + } + } + { + char path1[] = "aa/bb"; + cmCMakePath path2{ "cc/dd" }; + + path2.Assign(path1); + if (path2.String() != path1) { + result = false; + } + } + + checkResult(result); + + return result; +} + +bool testConcat() +{ + std::cout << "testConcat()"; + + bool result = true; + + { + cmCMakePath path1{ "aa/bb" }; + cmCMakePath path2{ "cc/dd" }; + + path2 += path1; + + if (path2.String() != "cc/ddaa/bb") { + result = false; + } + } + { + cmCMakePath path1{ "aa/bb" }; + cmCMakePath path2{ "cc/dd" }; + + path2 += std::move(path1); + if (path2.String() != "cc/ddaa/bb") { + result = false; + } + } + { + std::string path1{ "aa/bb" }; + cmCMakePath path2{ "cc/dd" }; + + path2 += path1; + if (path2.String() != "cc/ddaa/bb") { + result = false; + } + } + { + std::string path1{ "aa/bb" }; + cmCMakePath path2{ "cc/dd" }; + + path2 += std::move(path1); + if (path2.String() != "cc/ddaa/bb") { + result = false; + } + } + { + cm::string_view path1{ "aa/bb" }; + cmCMakePath path2{ "cc/dd" }; + + path2 += path1; + if (path2.String() != "cc/ddaa/bb") { + result = false; + } + } + { + char path1[] = "aa/bb"; + cmCMakePath path2{ "cc/dd" }; + + path2 += path1; + if (path2.String() != "cc/ddaa/bb") { + result = false; + } + } + { + cmCMakePath path1{ "aa/bb" }; + cmCMakePath path2{ "cc/dd" }; + + path2.Concat(path1); + if (path2.String() != "cc/ddaa/bb") { + result = false; + } + } + { + std::string path1{ "aa/bb" }; + cmCMakePath path2{ "cc/dd" }; + + path2.Concat(path1); + if (path2.String() != "cc/ddaa/bb") { + result = false; + } + } + { + std::string path1{ "aa/bb" }; + cmCMakePath path2{ "cc/dd" }; + + path2.Concat(std::move(path1)); + if (path2.String() != "cc/ddaa/bb") { + result = false; + } + } + { + cm::string_view path1{ "aa/bb" }; + cmCMakePath path2{ "cc/dd" }; + + path2.Concat(path1); + if (path2.String() != "cc/ddaa/bb") { + result = false; + } + } + { + char path1[] = "aa/bb"; + cmCMakePath path2{ "cc/dd" }; + + path2.Concat(path1); + if (path2.String() != "cc/ddaa/bb") { + result = false; + } + } + + checkResult(result); + + return result; +} + +bool testAppend() +{ + std::cout << "testAppend()"; + + bool result = true; + + { + cmCMakePath path1{ "aa/bb" }; + cmCMakePath path2{ "cc/dd" }; + + path2 /= path1; + + if (path2.String() != "cc/dd/aa/bb") { + result = false; + } + } + { + cmCMakePath path1{ "aa/bb" }; + cmCMakePath path2{ "cc/dd" }; + + path2 /= std::move(path1); + if (path2.String() != "cc/dd/aa/bb") { + result = false; + } + } + { + std::string path1{ "aa/bb" }; + cmCMakePath path2{ "cc/dd" }; + + path2 /= path1; + if (path2.String() != "cc/dd/aa/bb") { + result = false; + } + } + { + std::string path1{ "aa/bb" }; + cmCMakePath path2{ "cc/dd" }; + + path2 /= std::move(path1); + if (path2.String() != "cc/dd/aa/bb") { + result = false; + } + } + { + cm::string_view path1{ "aa/bb" }; + cmCMakePath path2{ "cc/dd" }; + + path2 /= path1; + if (path2.String() != "cc/dd/aa/bb") { + result = false; + } + } + { + char path1[] = "aa/bb"; + cmCMakePath path2{ "cc/dd" }; + + path2 /= path1; + if (path2.String() != "cc/dd/aa/bb") { + result = false; + } + } + { + cmCMakePath path1{ "aa/bb" }; + cmCMakePath path2{ "cc/dd" }; + + path2.Append(path1); + if (path2.String() != "cc/dd/aa/bb") { + result = false; + } + } + { + std::string path1{ "aa/bb" }; + cmCMakePath path2{ "cc/dd" }; + + path2.Append(path1); + if (path2.String() != "cc/dd/aa/bb") { + result = false; + } + } + { + std::string path1{ "aa/bb" }; + cmCMakePath path2{ "cc/dd" }; + + path2.Append(std::move(path1)); + if (path2.String() != "cc/dd/aa/bb") { + result = false; + } + } + { + cm::string_view path1{ "aa/bb" }; + cmCMakePath path2{ "cc/dd" }; + + path2.Append(path1); + if (path2.String() != "cc/dd/aa/bb") { + result = false; + } + } + { + char path1[] = "aa/bb"; + cmCMakePath path2{ "cc/dd" }; + + path2.Append(path1); + if (path2.String() != "cc/dd/aa/bb") { + result = false; + } + } + + checkResult(result); + + return result; +} +} + +int testCMakePath(int /*unused*/, char* /*unused*/[]) +{ + int result = 0; + + if (!testConstructors()) { + result = 1; + } + if (!testAssign()) { + result = 1; + } + if (!testConcat()) { + result = 1; + } + if (!testAppend()) { + result = 1; + } + + return result; +} |