summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2023-07-19 14:39:46 (GMT)
committerKitware Robot <kwrobot@kitware.com>2023-07-19 14:40:02 (GMT)
commite92156614280bece5452c85865f41d44082b1026 (patch)
tree6865102f51cc985b450af135350acc21503a86fb
parenta594748cdf61146279cfd88f6c21e340e85af8c1 (diff)
parent945b9b8132e9d9eead61e2874bc0e00e9ae23270 (diff)
downloadCMake-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.cxx2
-rw-r--r--Source/cmCMakePath.h213
-rw-r--r--Tests/CMakeLib/CMakeLists.txt1
-rw-r--r--Tests/CMakeLib/testCMakePath.cxx441
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;
+}