diff options
-rw-r--r-- | Source/cmGeneratorExpressionNode.cxx | 2 | ||||
-rw-r--r-- | Source/cmQtAutoGenInitializer.cxx | 1 | ||||
-rw-r--r-- | Source/cmString.hxx | 212 | ||||
-rw-r--r-- | Tests/CMakeLib/testString.cxx | 10 |
4 files changed, 170 insertions, 55 deletions
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx index 66f1c71..14478c2 100644 --- a/Source/cmGeneratorExpressionNode.cxx +++ b/Source/cmGeneratorExpressionNode.cxx @@ -14,6 +14,7 @@ #include <utility> #include <cm/iterator> +#include <cm/string_view> #include "cmsys/RegularExpression.hxx" #include "cmsys/String.h" @@ -37,7 +38,6 @@ #include "cmState.h" #include "cmStateSnapshot.h" #include "cmStateTypes.h" -#include "cmString.hxx" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx index ebb522b..acd85a0 100644 --- a/Source/cmQtAutoGenInitializer.cxx +++ b/Source/cmQtAutoGenInitializer.cxx @@ -42,7 +42,6 @@ #include "cmSourceGroup.h" #include "cmState.h" #include "cmStateTypes.h" -#include "cmString.hxx" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" diff --git a/Source/cmString.hxx b/Source/cmString.hxx index 073f4c9..9e91986 100644 --- a/Source/cmString.hxx +++ b/Source/cmString.hxx @@ -88,18 +88,6 @@ struct IntoString<std::string> : std::true_type }; template <> -struct IntoString<string_view> : std::true_type -{ - static std::string into_string(string_view s) { return std::string(s); } -}; - -template <> -struct IntoString<static_string_view> : std::true_type -{ - static string_view into_string(static_string_view s) { return s; } -}; - -template <> struct IntoString<char> : std::true_type { static std::string into_string(char const& c) { return std::string(1, c); } @@ -239,6 +227,25 @@ public: { } + /** + * Construct via static_string_view constructor. + * explicit is required to avoid ambiguous overloaded operators (i.e ==, + * etc...) with the ones provided by string_view. + */ + explicit String(static_string_view s) + : String(s, Private()) + { + } + /** + * Construct via string_view constructor. + * explicit is required to avoid ambiguous overloaded operators (i.e ==, + * etc...) with the ones provided by string_view. + */ + explicit String(string_view s) + : String(std::string(s), Private()) + { + } + /** Construct via std::string initializer list constructor. */ String(std::initializer_list<char> il) : String(std::string(il)) @@ -306,6 +313,17 @@ public: This shares ownership of the other string's buffer. */ String& operator=(String const&) noexcept = default; + String& operator=(static_string_view s) + { + *this = String(s); + return *this; + } + String& operator=(string_view s) + { + *this = String(s); + return *this; + } + /** Assign from any type implementing the IntoString trait. */ template <typename T> typename // NOLINT(*) @@ -328,6 +346,7 @@ public: /** Return a view of the string. */ string_view view() const noexcept { return view_; } + operator string_view() const noexcept { return this->view(); } /** Return true if the instance is an empty stringn or null string. */ bool empty() const noexcept { return view_.empty(); } @@ -638,58 +657,155 @@ private: string_view view_; }; -template <typename L, typename R> -typename std::enable_if<AsStringView<L>::value && AsStringView<R>::value, - bool>::type -operator==(L&& l, R&& r) +/** + * Trait for comparable types. + */ +template <typename T> +struct IsComparable : std::false_type +{ +}; + +template <typename T> +struct IsComparable<T&> : IsComparable<T> +{ +}; + +template <typename T> +struct IsComparable<T const> : IsComparable<T> +{ +}; + +template <typename T> +struct IsComparable<T const*> : IsComparable<T*> +{ +}; + +template <typename T, std::string::size_type N> +struct IsComparable<T const[N]> : IsComparable<T[N]> +{ +}; + +template <> +struct IsComparable<char*> : std::true_type { - return (AsStringView<L>::view(std::forward<L>(l)) == - AsStringView<R>::view(std::forward<R>(r))); +}; + +template <std::string::size_type N> +struct IsComparable<char[N]> : std::true_type +{ +}; + +template <> +struct IsComparable<std::string> : std::true_type +{ +}; + +template <> +struct IsComparable<char> : std::true_type +{ +}; + +/** comparison operators */ +inline bool operator==(const String& l, const String& r) +{ + return l.view() == r.view(); +} +template <typename L> +typename std::enable_if<IsComparable<L>::value, bool>::type operator==( + L&& l, const String& r) +{ + return AsStringView<L>::view(std::forward<L>(l)) == r.view(); +} +template <typename R> +typename std::enable_if<IsComparable<R>::value, bool>::type operator==( + const String& l, R&& r) +{ + return l.view() == AsStringView<R>::view(std::forward<R>(r)); } -template <typename L, typename R> -typename std::enable_if<AsStringView<L>::value && AsStringView<R>::value, - bool>::type -operator!=(L&& l, R&& r) +inline bool operator!=(const String& l, const String& r) +{ + return l.view() != r.view(); +} +template <typename L> +typename std::enable_if<IsComparable<L>::value, bool>::type operator!=( + L&& l, const String& r) { - return (AsStringView<L>::view(std::forward<L>(l)) != - AsStringView<R>::view(std::forward<R>(r))); + return AsStringView<L>::view(std::forward<L>(l)) != r.view(); +} +template <typename R> +typename std::enable_if<IsComparable<R>::value, bool>::type operator!=( + const String& l, R&& r) +{ + return l.view() != AsStringView<R>::view(std::forward<R>(r)); } -template <typename L, typename R> -typename std::enable_if<AsStringView<L>::value && AsStringView<R>::value, - bool>::type -operator<(L&& l, R&& r) +inline bool operator<(const String& l, const String& r) { - return (AsStringView<L>::view(std::forward<L>(l)) < - AsStringView<R>::view(std::forward<R>(r))); + return l.view() < r.view(); +} +template <typename L> +typename std::enable_if<IsComparable<L>::value, bool>::type operator<( + L&& l, const String& r) +{ + return AsStringView<L>::view(std::forward<L>(l)) < r.view(); +} +template <typename R> +typename std::enable_if<IsComparable<R>::value, bool>::type operator<( + const String& l, R&& r) +{ + return l.view() < AsStringView<R>::view(std::forward<R>(r)); } -template <typename L, typename R> -typename std::enable_if<AsStringView<L>::value && AsStringView<R>::value, - bool>::type -operator<=(L&& l, R&& r) +inline bool operator<=(const String& l, const String& r) +{ + return l.view() <= r.view(); +} +template <typename L> +typename std::enable_if<IsComparable<L>::value, bool>::type operator<=( + L&& l, const String& r) +{ + return AsStringView<L>::view(std::forward<L>(l)) <= r.view(); +} +template <typename R> +typename std::enable_if<IsComparable<R>::value, bool>::type operator<=( + const String& l, R&& r) { - return (AsStringView<L>::view(std::forward<L>(l)) <= - AsStringView<R>::view(std::forward<R>(r))); + return l.view() <= AsStringView<R>::view(std::forward<R>(r)); } -template <typename L, typename R> -typename std::enable_if<AsStringView<L>::value && AsStringView<R>::value, - bool>::type -operator>(L&& l, R&& r) +inline bool operator>(const String& l, const String& r) +{ + return l.view() > r.view(); +} +template <typename L> +typename std::enable_if<IsComparable<L>::value, bool>::type operator>( + L&& l, const String& r) +{ + return AsStringView<L>::view(std::forward<L>(l)) > r.view(); +} +template <typename R> +typename std::enable_if<IsComparable<R>::value, bool>::type operator>( + const String& l, R&& r) { - return (AsStringView<L>::view(std::forward<L>(l)) > - AsStringView<R>::view(std::forward<R>(r))); + return l.view() > AsStringView<R>::view(std::forward<R>(r)); } -template <typename L, typename R> -typename std::enable_if<AsStringView<L>::value && AsStringView<R>::value, - bool>::type -operator>=(L&& l, R&& r) +inline bool operator>=(const String& l, const String& r) +{ + return l.view() >= r.view(); +} +template <typename L> +typename std::enable_if<IsComparable<L>::value, bool>::type operator>=( + L&& l, const String& r) +{ + return AsStringView<L>::view(std::forward<L>(l)) >= r.view(); +} +template <typename R> +typename std::enable_if<IsComparable<R>::value, bool>::type operator>=( + const String& l, R&& r) { - return (AsStringView<L>::view(std::forward<L>(l)) >= - AsStringView<R>::view(std::forward<R>(r))); + return l.view() >= AsStringView<R>::view(std::forward<R>(r)); } std::ostream& operator<<(std::ostream& os, String const& s); diff --git a/Tests/CMakeLib/testString.cxx b/Tests/CMakeLib/testString.cxx index d7b3200..1fd3f38 100644 --- a/Tests/CMakeLib/testString.cxx +++ b/Tests/CMakeLib/testString.cxx @@ -191,7 +191,7 @@ static bool testConstructFromView() { std::cout << "testConstructFromView()\n"; cm::string_view view = cstr; - return testFromCStr(view); + return testFromCStr(cm::String(view)); } static bool testAssignFromView() @@ -297,7 +297,7 @@ static bool testFromStaticStringView(cm::String str) static bool testConstructFromStaticStringView() { std::cout << "testConstructFromStaticStringView()\n"; - return testFromStaticStringView(staticStringView); + return testFromStaticStringView(cm::String(staticStringView)); } static bool testAssignFromStaticStringView() @@ -796,7 +796,7 @@ static bool testMethod_substr_AtEnd(cm::String str) static bool testMethod_substr_AtEndBorrowed() { std::cout << "testMethod_substr_AtEndBorrowed()\n"; - return testMethod_substr_AtEnd("abc"_s); + return testMethod_substr_AtEnd(cm::String("abc"_s)); } static bool testMethod_substr_AtEndOwned() @@ -855,7 +855,7 @@ static bool testMethod_substr_AtStart(cm::String str) static bool testMethod_substr_AtStartBorrowed() { std::cout << "testMethod_substr_AtStartBorrowed()\n"; - return testMethod_substr_AtStart("abc"_s); + return testMethod_substr_AtStart(cm::String("abc"_s)); } static bool testMethod_substr_AtStartOwned() @@ -1146,7 +1146,7 @@ static bool testAddition() static bool testStability() { std::cout << "testStability()\n"; - cm::String str = "abc"_s; + cm::String str("abc"_s); ASSERT_TRUE(!str.is_stable()); ASSERT_TRUE(str.str_if_stable() == nullptr); str.stabilize(); |