cm::String: enhance compatibility with STL

This commit is contained in:
Marc Chevrier
2020-01-24 12:16:58 +01:00
parent 33e7bd66c0
commit 8f839d02e3
4 changed files with 170 additions and 55 deletions
+1 -1
View File
@@ -14,6 +14,7 @@
#include <utility> #include <utility>
#include <cm/iterator> #include <cm/iterator>
#include <cm/string_view>
#include "cmsys/RegularExpression.hxx" #include "cmsys/RegularExpression.hxx"
#include "cmsys/String.h" #include "cmsys/String.h"
@@ -37,7 +38,6 @@
#include "cmState.h" #include "cmState.h"
#include "cmStateSnapshot.h" #include "cmStateSnapshot.h"
#include "cmStateTypes.h" #include "cmStateTypes.h"
#include "cmString.hxx"
#include "cmStringAlgorithms.h" #include "cmStringAlgorithms.h"
#include "cmSystemTools.h" #include "cmSystemTools.h"
#include "cmTarget.h" #include "cmTarget.h"
-1
View File
@@ -42,7 +42,6 @@
#include "cmSourceGroup.h" #include "cmSourceGroup.h"
#include "cmState.h" #include "cmState.h"
#include "cmStateTypes.h" #include "cmStateTypes.h"
#include "cmString.hxx"
#include "cmStringAlgorithms.h" #include "cmStringAlgorithms.h"
#include "cmSystemTools.h" #include "cmSystemTools.h"
#include "cmTarget.h" #include "cmTarget.h"
+164 -48
View File
@@ -87,18 +87,6 @@ struct IntoString<std::string> : std::true_type
static std::string into_string(std::string s) { return s; } static std::string into_string(std::string s) { return s; }
}; };
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 <> template <>
struct IntoString<char> : std::true_type struct IntoString<char> : std::true_type
{ {
@@ -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. */ /** Construct via std::string initializer list constructor. */
String(std::initializer_list<char> il) String(std::initializer_list<char> il)
: String(std::string(il)) : String(std::string(il))
@@ -306,6 +313,17 @@ public:
This shares ownership of the other string's buffer. */ This shares ownership of the other string's buffer. */
String& operator=(String const&) noexcept = default; 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. */ /** Assign from any type implementing the IntoString trait. */
template <typename T> template <typename T>
typename // NOLINT(*) typename // NOLINT(*)
@@ -328,6 +346,7 @@ public:
/** Return a view of the string. */ /** Return a view of the string. */
string_view view() const noexcept { return view_; } 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. */ /** Return true if the instance is an empty stringn or null string. */
bool empty() const noexcept { return view_.empty(); } bool empty() const noexcept { return view_.empty(); }
@@ -638,58 +657,155 @@ private:
string_view view_; string_view view_;
}; };
template <typename L, typename R> /**
typename std::enable_if<AsStringView<L>::value && AsStringView<R>::value, * Trait for comparable types.
bool>::type */
operator==(L&& l, R&& r) template <typename T>
struct IsComparable : std::false_type
{ {
return (AsStringView<L>::view(std::forward<L>(l)) == };
AsStringView<R>::view(std::forward<R>(r)));
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
{
};
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> inline bool operator!=(const String& l, const String& r)
typename std::enable_if<AsStringView<L>::value && AsStringView<R>::value,
bool>::type
operator!=(L&& l, R&& r)
{ {
return (AsStringView<L>::view(std::forward<L>(l)) != return l.view() != r.view();
AsStringView<R>::view(std::forward<R>(r))); }
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> inline bool operator<(const String& l, const String& r)
typename std::enable_if<AsStringView<L>::value && AsStringView<R>::value,
bool>::type
operator<(L&& l, R&& r)
{ {
return (AsStringView<L>::view(std::forward<L>(l)) < return l.view() < r.view();
AsStringView<R>::view(std::forward<R>(r))); }
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> inline bool operator<=(const String& l, const String& r)
typename std::enable_if<AsStringView<L>::value && AsStringView<R>::value,
bool>::type
operator<=(L&& l, R&& r)
{ {
return (AsStringView<L>::view(std::forward<L>(l)) <= return l.view() <= r.view();
AsStringView<R>::view(std::forward<R>(r))); }
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> inline bool operator>(const String& l, const String& r)
typename std::enable_if<AsStringView<L>::value && AsStringView<R>::value,
bool>::type
operator>(L&& l, R&& r)
{ {
return (AsStringView<L>::view(std::forward<L>(l)) > return l.view() > r.view();
AsStringView<R>::view(std::forward<R>(r))); }
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> inline bool operator>=(const String& l, const String& r)
typename std::enable_if<AsStringView<L>::value && AsStringView<R>::value,
bool>::type
operator>=(L&& l, R&& r)
{ {
return (AsStringView<L>::view(std::forward<L>(l)) >= return l.view() >= r.view();
AsStringView<R>::view(std::forward<R>(r))); }
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));
} }
std::ostream& operator<<(std::ostream& os, String const& s); std::ostream& operator<<(std::ostream& os, String const& s);
+5 -5
View File
@@ -191,7 +191,7 @@ static bool testConstructFromView()
{ {
std::cout << "testConstructFromView()\n"; std::cout << "testConstructFromView()\n";
cm::string_view view = cstr; cm::string_view view = cstr;
return testFromCStr(view); return testFromCStr(cm::String(view));
} }
static bool testAssignFromView() static bool testAssignFromView()
@@ -297,7 +297,7 @@ static bool testFromStaticStringView(cm::String str)
static bool testConstructFromStaticStringView() static bool testConstructFromStaticStringView()
{ {
std::cout << "testConstructFromStaticStringView()\n"; std::cout << "testConstructFromStaticStringView()\n";
return testFromStaticStringView(staticStringView); return testFromStaticStringView(cm::String(staticStringView));
} }
static bool testAssignFromStaticStringView() static bool testAssignFromStaticStringView()
@@ -796,7 +796,7 @@ static bool testMethod_substr_AtEnd(cm::String str)
static bool testMethod_substr_AtEndBorrowed() static bool testMethod_substr_AtEndBorrowed()
{ {
std::cout << "testMethod_substr_AtEndBorrowed()\n"; 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() static bool testMethod_substr_AtEndOwned()
@@ -855,7 +855,7 @@ static bool testMethod_substr_AtStart(cm::String str)
static bool testMethod_substr_AtStartBorrowed() static bool testMethod_substr_AtStartBorrowed()
{ {
std::cout << "testMethod_substr_AtStartBorrowed()\n"; 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() static bool testMethod_substr_AtStartOwned()
@@ -1146,7 +1146,7 @@ static bool testAddition()
static bool testStability() static bool testStability()
{ {
std::cout << "testStability()\n"; std::cout << "testStability()\n";
cm::String str = "abc"_s; cm::String str("abc"_s);
ASSERT_TRUE(!str.is_stable()); ASSERT_TRUE(!str.is_stable());
ASSERT_TRUE(str.str_if_stable() == nullptr); ASSERT_TRUE(str.str_if_stable() == nullptr);
str.stabilize(); str.stabilize();