diff --git a/llvm/include/llvm/ADT/ArrayRef.h b/llvm/include/llvm/ADT/ArrayRef.h --- a/llvm/include/llvm/ADT/ArrayRef.h +++ b/llvm/include/llvm/ADT/ArrayRef.h @@ -23,6 +23,10 @@ #include #include +#if __cpp_lib_span +#include +#endif + namespace llvm { template class [[nodiscard]] MutableArrayRef; @@ -144,6 +148,12 @@ * = nullptr) : Data(Vec.data()), Length(Vec.size()) {} +#if __cpp_lib_span + /// Construct an array ref from a C++ standard span + ArrayRef(const std::span &Span) + : Data(Span.data()), Length(Span.size()) {} +#endif + /// @} /// @name Simple Operations /// @{ @@ -188,6 +198,15 @@ return std::equal(begin(), end(), RHS.begin()); } +#if __cpp_lib_span + /// equals - Check for element-wise equality. + bool equals(std::span RHS) const { + if (Length != RHS.Length) + return false; + return std::equal(begin(), end(), RHS.begin()); + } +#endif + /// slice(n, m) - Chop off the first N elements of the array, and keep M /// elements in the array. ArrayRef slice(size_t N, size_t M) const { @@ -286,6 +305,11 @@ return std::vector(Data, Data+Length); } +#if __cpp_lib_span + /// Construct an array ref from a C++ standard span + operator std::span() { return std::span(Data, Length); } +#endif + /// @} }; diff --git a/llvm/include/llvm/ADT/StringExtras.h b/llvm/include/llvm/ADT/StringExtras.h --- a/llvm/include/llvm/ADT/StringExtras.h +++ b/llvm/include/llvm/ADT/StringExtras.h @@ -51,6 +51,17 @@ return Result; } +/// Given an array of c-style strings terminated by a null pointer, construct +/// a vector of string_views representing the same strings without the +/// terminating null string. +inline std::vector +toStringViewArray(const char *const *Strings) { + std::vector Result; + while (*Strings) + Result.push_back(*Strings++); + return Result; +} + /// Construct a string ref from a boolean. inline StringRef toStringRef(bool B) { return StringRef(B ? "true" : "false"); } @@ -59,6 +70,12 @@ return StringRef(reinterpret_cast(Input.begin()), Input.size()); } +/// Construct a string ref from an array ref of unsigned chars. +inline std::string_view toStringView(ArrayRef Input) { + return std::string_view(reinterpret_cast(Input.begin()), + Input.size()); +} + /// Construct a string ref from an array ref of unsigned chars. inline ArrayRef arrayRefFromStringRef(StringRef Input) { return {Input.bytes_begin(), Input.bytes_end()}; diff --git a/llvm/include/llvm/ADT/StringRef.h b/llvm/include/llvm/ADT/StringRef.h --- a/llvm/include/llvm/ADT/StringRef.h +++ b/llvm/include/llvm/ADT/StringRef.h @@ -166,6 +166,25 @@ compareMemory(Data, RHS.Data, RHS.Length) == 0); } + /// equals - Check for string equality, this is more efficient than + /// compare() when the relative ordering of inequal strings isn't needed. + [[nodiscard]] bool equals(std::string_view RHS) const { + return (Length == RHS.length() && + compareMemory(Data, RHS.data(), RHS.length()) == 0); + } + + /// equals - Check for string equality, this is more efficient than + /// compare() when the relative ordering of inequal strings isn't needed. + [[nodiscard]] bool equals(const char *RHS) const { + return equals((StringRef)RHS); + } + + /// equals - Check for string equality, this is more efficient than + /// compare() when the relative ordering of inequal strings isn't needed. + [[nodiscard]] bool equals(std::string RHS) const { + return equals((StringRef)RHS); + } + /// Check for string equality, ignoring case. [[nodiscard]] bool equals_insensitive(StringRef RHS) const { return Length == RHS.Length && compare_insensitive(RHS) == 0; @@ -872,6 +891,30 @@ inline bool operator!=(StringRef LHS, StringRef RHS) { return !(LHS == RHS); } + inline bool operator==(StringRef LHS, std::string_view RHS) { + return LHS.equals(RHS); + } + + inline bool operator!=(StringRef LHS, std::string_view RHS) { + return !(LHS == RHS); + } + + inline bool operator==(StringRef LHS, const char *RHS) { + return LHS.equals((StringRef)RHS); + } + + inline bool operator!=(StringRef LHS, const char *RHS) { + return !(LHS == RHS); + } + + inline bool operator==(StringRef LHS, std::string RHS) { + return LHS.equals((StringRef)RHS); + } + + inline bool operator!=(StringRef LHS, std::string RHS) { + return !(LHS == RHS); + } + inline bool operator<(StringRef LHS, StringRef RHS) { return LHS.compare(RHS) < 0; }