123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- #ifndef C10_UTIL_STRINGUTIL_H_
- #define C10_UTIL_STRINGUTIL_H_
- #include <c10/macros/Macros.h>
- #include <c10/util/string_utils.h>
- #include <c10/util/string_view.h>
- #include <cstddef>
- #include <ostream>
- #include <sstream>
- #include <string>
- #include <vector>
- C10_CLANG_DIAGNOSTIC_PUSH()
- #if C10_CLANG_HAS_WARNING("-Wshorten-64-to-32")
- C10_CLANG_DIAGNOSTIC_IGNORE("-Wshorten-64-to-32")
- #endif
- namespace c10 {
- namespace detail {
- // Obtains the base name from a full path.
- C10_API std::string StripBasename(const std::string& full_path);
- C10_API std::string ExcludeFileExtension(const std::string& full_path);
- struct CompileTimeEmptyString {
- operator const std::string&() const {
- static const std::string empty_string_literal;
- return empty_string_literal;
- }
- operator const char*() const {
- return "";
- }
- };
- template <typename T>
- struct CanonicalizeStrTypes {
- using type = const T&;
- };
- template <size_t N>
- struct CanonicalizeStrTypes<char[N]> {
- using type = const char*;
- };
- inline std::ostream& _str(std::ostream& ss) {
- return ss;
- }
- template <typename T>
- inline std::ostream& _str(std::ostream& ss, const T& t) {
- // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage)
- ss << t;
- return ss;
- }
- template <>
- inline std::ostream& _str<CompileTimeEmptyString>(
- std::ostream& ss,
- const CompileTimeEmptyString&) {
- return ss;
- }
- template <typename T, typename... Args>
- inline std::ostream& _str(std::ostream& ss, const T& t, const Args&... args) {
- return _str(_str(ss, t), args...);
- }
- template <typename... Args>
- struct _str_wrapper final {
- static std::string call(const Args&... args) {
- std::ostringstream ss;
- _str(ss, args...);
- return ss.str();
- }
- };
- // Specializations for already-a-string types.
- template <>
- struct _str_wrapper<std::string> final {
- // return by reference to avoid the binary size of a string copy
- static const std::string& call(const std::string& str) {
- return str;
- }
- };
- template <>
- struct _str_wrapper<const char*> final {
- static const char* call(const char* str) {
- return str;
- }
- };
- // For c10::str() with an empty argument list (which is common in our assert
- // macros), we don't want to pay the binary size for constructing and
- // destructing a stringstream or even constructing a string.
- template <>
- struct _str_wrapper<> final {
- static CompileTimeEmptyString call() {
- return CompileTimeEmptyString();
- }
- };
- } // namespace detail
- // Convert a list of string-like arguments into a single string.
- template <typename... Args>
- inline decltype(auto) str(const Args&... args) {
- return detail::_str_wrapper<
- typename detail::CanonicalizeStrTypes<Args>::type...>::call(args...);
- }
- template <class Container>
- inline std::string Join(const std::string& delimiter, const Container& v) {
- std::stringstream s;
- int cnt = static_cast<int64_t>(v.size()) - 1;
- for (auto i = v.begin(); i != v.end(); ++i, --cnt) {
- s << (*i) << (cnt ? delimiter : "");
- }
- return s.str();
- }
- // Replace all occurrences of "from" substring to "to" string.
- // Returns number of replacements
- size_t C10_API
- ReplaceAll(std::string& s, c10::string_view from, c10::string_view to);
- /// Represents a location in source code (for debugging).
- struct C10_API SourceLocation {
- const char* function;
- const char* file;
- uint32_t line;
- };
- std::ostream& operator<<(std::ostream& out, const SourceLocation& loc);
- // unix isprint but insensitive to locale
- inline static bool isPrint(char s) {
- return s > 0x1f && s < 0x7f;
- }
- inline void printQuotedString(std::ostream& stmt, const string_view str) {
- stmt << "\"";
- for (auto s : str) {
- switch (s) {
- case '\\':
- stmt << "\\\\";
- break;
- case '\'':
- stmt << "\\'";
- break;
- case '\"':
- stmt << "\\\"";
- break;
- case '\a':
- stmt << "\\a";
- break;
- case '\b':
- stmt << "\\b";
- break;
- case '\f':
- stmt << "\\f";
- break;
- case '\n':
- stmt << "\\n";
- break;
- case '\r':
- stmt << "\\r";
- break;
- case '\t':
- stmt << "\\t";
- break;
- case '\v':
- stmt << "\\v";
- break;
- default:
- if (isPrint(s)) {
- stmt << s;
- } else {
- // C++ io has stateful formatting settings. Messing with
- // them is probably worse than doing this manually.
- char buf[4] = "000";
- buf[2] += s % 8;
- s /= 8;
- buf[1] += s % 8;
- s /= 8;
- buf[0] += s;
- stmt << "\\" << buf;
- }
- break;
- }
- }
- stmt << "\"";
- }
- } // namespace c10
- C10_CLANG_DIAGNOSTIC_POP()
- #endif // C10_UTIL_STRINGUTIL_H_
|