//===- llvm/ADT/StringExtras.h - Useful string functions --------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// /// \file /// This file contains some functions that are useful when dealing with strings. /// //===----------------------------------------------------------------------===// #ifndef LLVM_ADT_STRINGEXTRAS_H #define LLVM_ADT_STRINGEXTRAS_H #include "llvm/ADT/APSInt.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" #include <cassert> #include <cstddef> #include <cstdint> #include <cstdlib> #include <cstring> #include <iterator> #include <string> #include <utility> namespace llvm { class raw_ostream; /// hexdigit - Return the hexadecimal character for the /// given number \p X (which should be less than 16). inline char hexdigit(unsigned X, bool LowerCase = false) { … } /// Given an array of c-style strings terminated by a null pointer, construct /// a vector of StringRefs representing the same strings without the terminating /// null string. inline std::vector<StringRef> toStringRefArray(const char *const *Strings) { … } /// Construct a string ref from a boolean. inline StringRef toStringRef(bool B) { … } /// Construct a string ref from an array ref of unsigned chars. inline StringRef toStringRef(ArrayRef<uint8_t> Input) { … } inline StringRef toStringRef(ArrayRef<char> Input) { … } /// Construct a string ref from an array ref of unsigned chars. template <class CharT = uint8_t> inline ArrayRef<CharT> arrayRefFromStringRef(StringRef Input) { … } /// Interpret the given character \p C as a hexadecimal digit and return its /// value. /// /// If \p C is not a valid hex digit, -1U is returned. inline unsigned hexDigitValue(char C) { … } /// Checks if character \p C is one of the 10 decimal digits. inline bool isDigit(char C) { … } /// Checks if character \p C is a hexadecimal numeric character. inline bool isHexDigit(char C) { … } /// Checks if character \p C is a lowercase letter as classified by "C" locale. inline bool isLower(char C) { … } /// Checks if character \p C is a uppercase letter as classified by "C" locale. inline bool isUpper(char C) { … } /// Checks if character \p C is a valid letter as classified by "C" locale. inline bool isAlpha(char C) { … } /// Checks whether character \p C is either a decimal digit or an uppercase or /// lowercase letter as classified by "C" locale. inline bool isAlnum(char C) { … } /// Checks whether character \p C is valid ASCII (high bit is zero). inline bool isASCII(char C) { … } /// Checks whether all characters in S are ASCII. inline bool isASCII(llvm::StringRef S) { … } /// Checks whether character \p C is printable. /// /// Locale-independent version of the C standard library isprint whose results /// may differ on different platforms. inline bool isPrint(char C) { … } /// Checks whether character \p C is a punctuation character. /// /// Locale-independent version of the C standard library ispunct. The list of /// punctuation characters can be found in the documentation of std::ispunct: /// https://en.cppreference.com/w/cpp/string/byte/ispunct. inline bool isPunct(char C) { … } /// Checks whether character \p C is whitespace in the "C" locale. /// /// Locale-independent version of the C standard library isspace. inline bool isSpace(char C) { … } /// Returns the corresponding lowercase character if \p x is uppercase. inline char toLower(char x) { … } /// Returns the corresponding uppercase character if \p x is lowercase. inline char toUpper(char x) { … } inline std::string utohexstr(uint64_t X, bool LowerCase = false, unsigned Width = 0) { … } /// Convert buffer \p Input to its hexadecimal representation. /// The returned string is double the size of \p Input. inline void toHex(ArrayRef<uint8_t> Input, bool LowerCase, SmallVectorImpl<char> &Output) { … } inline std::string toHex(ArrayRef<uint8_t> Input, bool LowerCase = false) { … } inline std::string toHex(StringRef Input, bool LowerCase = false) { … } /// Store the binary representation of the two provided values, \p MSB and /// \p LSB, that make up the nibbles of a hexadecimal digit. If \p MSB or \p LSB /// do not correspond to proper nibbles of a hexadecimal digit, this method /// returns false. Otherwise, returns true. inline bool tryGetHexFromNibbles(char MSB, char LSB, uint8_t &Hex) { … } /// Return the binary representation of the two provided values, \p MSB and /// \p LSB, that make up the nibbles of a hexadecimal digit. inline uint8_t hexFromNibbles(char MSB, char LSB) { … } /// Convert hexadecimal string \p Input to its binary representation and store /// the result in \p Output. Returns true if the binary representation could be /// converted from the hexadecimal string. Returns false if \p Input contains /// non-hexadecimal digits. The output string is half the size of \p Input. inline bool tryGetFromHex(StringRef Input, std::string &Output) { … } /// Convert hexadecimal string \p Input to its binary representation. /// The return string is half the size of \p Input. inline std::string fromHex(StringRef Input) { … } /// Convert the string \p S to an integer of the specified type using /// the radix \p Base. If \p Base is 0, auto-detects the radix. /// Returns true if the number was successfully converted, false otherwise. template <typename N> bool to_integer(StringRef S, N &Num, unsigned Base = 0) { … } namespace detail { template <typename N> inline bool to_float(const Twine &T, N &Num, N (*StrTo)(const char *, char **)) { … } } inline bool to_float(const Twine &T, float &Num) { … } inline bool to_float(const Twine &T, double &Num) { … } inline bool to_float(const Twine &T, long double &Num) { … } inline std::string utostr(uint64_t X, bool isNeg = false) { … } inline std::string itostr(int64_t X) { … } inline std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral = false, bool UpperCase = true, bool InsertSeparators = false) { … } inline std::string toString(const APSInt &I, unsigned Radix) { … } /// StrInStrNoCase - Portable version of strcasestr. Locates the first /// occurrence of string 's1' in string 's2', ignoring case. Returns /// the offset of s2 in s1 or npos if s2 cannot be found. StringRef::size_type StrInStrNoCase(StringRef s1, StringRef s2); /// getToken - This function extracts one token from source, ignoring any /// leading characters that appear in the Delimiters string, and ending the /// token at any of the characters that appear in the Delimiters string. If /// there are no tokens in the source string, an empty string is returned. /// The function returns a pair containing the extracted token and the /// remaining tail string. std::pair<StringRef, StringRef> getToken(StringRef Source, StringRef Delimiters = " \t\n\v\f\r"); /// SplitString - Split up the specified string according to the specified /// delimiters, appending the result fragments to the output list. void SplitString(StringRef Source, SmallVectorImpl<StringRef> &OutFragments, StringRef Delimiters = " \t\n\v\f\r"); /// Returns the English suffix for an ordinal integer (-st, -nd, -rd, -th). inline StringRef getOrdinalSuffix(unsigned Val) { … } /// Print each character of the specified string, escaping it if it is not /// printable or if it is an escape char. void printEscapedString(StringRef Name, raw_ostream &Out); /// Print each character of the specified string, escaping HTML special /// characters. void printHTMLEscaped(StringRef String, raw_ostream &Out); /// printLowerCase - Print each character as lowercase if it is uppercase. void printLowerCase(StringRef String, raw_ostream &Out); /// Converts a string from camel-case to snake-case by replacing all uppercase /// letters with '_' followed by the letter in lowercase, except if the /// uppercase letter is the first character of the string. std::string convertToSnakeFromCamelCase(StringRef input); /// Converts a string from snake-case to camel-case by replacing all occurrences /// of '_' followed by a lowercase letter with the letter in uppercase. /// Optionally allow capitalization of the first letter (if it is a lowercase /// letter) std::string convertToCamelFromSnakeCase(StringRef input, bool capitalizeFirst = false); namespace detail { template <typename IteratorT> inline std::string join_impl(IteratorT Begin, IteratorT End, StringRef Separator, std::input_iterator_tag) { … } template <typename IteratorT> inline std::string join_impl(IteratorT Begin, IteratorT End, StringRef Separator, std::forward_iterator_tag) { … } template <typename Sep> inline void join_items_impl(std::string &Result, Sep Separator) { … } template <typename Sep, typename Arg> inline void join_items_impl(std::string &Result, Sep Separator, const Arg &Item) { … } template <typename Sep, typename Arg1, typename... Args> inline void join_items_impl(std::string &Result, Sep Separator, const Arg1 &A1, Args &&... Items) { … } inline size_t join_one_item_size(char) { … } inline size_t join_one_item_size(const char *S) { … } template <typename T> inline size_t join_one_item_size(const T &Str) { … } template <typename... Args> inline size_t join_items_size(Args &&...Items) { … } } // end namespace detail /// Joins the strings in the range [Begin, End), adding Separator between /// the elements. template <typename IteratorT> inline std::string join(IteratorT Begin, IteratorT End, StringRef Separator) { … } /// Joins the strings in the range [R.begin(), R.end()), adding Separator /// between the elements. template <typename Range> inline std::string join(Range &&R, StringRef Separator) { … } /// Joins the strings in the parameter pack \p Items, adding \p Separator /// between the elements. All arguments must be implicitly convertible to /// std::string, or there should be an overload of std::string::operator+=() /// that accepts the argument explicitly. template <typename Sep, typename... Args> inline std::string join_items(Sep Separator, Args &&... Items) { … } /// A helper class to return the specified delimiter string after the first /// invocation of operator StringRef(). Used to generate a comma-separated /// list from a loop like so: /// /// \code /// ListSeparator LS; /// for (auto &I : C) /// OS << LS << I.getName(); /// \end class ListSeparator { … }; /// A forward iterator over partitions of string over a separator. class SplittingIterator : public iterator_facade_base<SplittingIterator, std::forward_iterator_tag, StringRef> { … }; /// Split the specified string over a separator and return a range-compatible /// iterable over its partitions. Used to permit conveniently iterating /// over separated strings like so: /// /// \code /// for (StringRef x : llvm::split("foo,bar,baz", ",")) /// ...; /// \end /// /// Note that the passed string must remain valid throuhgout lifetime /// of the iterators. inline iterator_range<SplittingIterator> split(StringRef Str, StringRef Separator) { … } inline iterator_range<SplittingIterator> split(StringRef Str, char Separator) { … } } // end namespace llvm #endif // LLVM_ADT_STRINGEXTRAS_H