| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274 |
- #if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION)
- #ifndef C10_UTIL_STRINGUTIL_H_
- #define C10_UTIL_STRINGUTIL_H_
- #include <c10/macros/Macros.h>
- #include <c10/util/string_utils.h>
- #include <cstddef>
- #include <optional>
- #include <ostream>
- #include <sstream>
- #include <string>
- #include <string_view>
- #include <type_traits>
- #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>
- // NOLINTNEXTLINE(*c-arrays*)
- struct CanonicalizeStrTypes<char[N]> {
- using type = const char*;
- };
- inline std::ostream& _str(std::ostream& ss) {
- return ss;
- }
- template <class T, class = std::ostream&>
- struct Streamable : std::false_type {};
- template <class T>
- struct Streamable<T, decltype(std::declval<std::ostream&>() << T{})>
- : std::true_type {};
- template <typename T>
- inline std::ostream& _str(std::ostream& ss, const T& t) {
- if constexpr (std::is_enum_v<T> && !Streamable<T>::value) {
- // NOLINTNEXTLINE(modernize-type-traits)
- return _str(ss, static_cast<typename std::underlying_type<T>::type>(t));
- } else {
- // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage)
- ss << t;
- return ss;
- }
- }
- template <typename T>
- inline std::ostream& _str(std::ostream& ss, const std::optional<T>& t) {
- if (t.has_value()) {
- return _str(ss, t.value());
- }
- ss << "std::nullopt";
- return ss;
- }
- // Overloads of _str for wide types; forces narrowing.
- C10_API std::ostream& _str(std::ostream& ss, const wchar_t* wCStr);
- C10_API std::ostream& _str(std::ostream& ss, const wchar_t& wChar);
- C10_API std::ostream& _str(std::ostream& ss, const std::wstring& wString);
- template <>
- inline std::ostream& _str<CompileTimeEmptyString>(
- std::ostream& ss,
- const CompileTimeEmptyString& /*unused*/) {
- 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 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 std::move(s).str();
- }
- // Replace all occurrences of "from" substring to "to" string.
- // Returns number of replacements
- size_t C10_API
- ReplaceAll(std::string& s, std::string_view from, std::string_view to);
- /// Represents a location in source code (for debugging).
- struct C10_API SourceLocation {
- const char* function;
- const char* file;
- uint32_t line;
- static constexpr SourceLocation current(
- const char* file = __builtin_FILE(),
- const char* function = __builtin_FUNCTION(),
- const std::uint_least32_t line = __builtin_LINE()) noexcept {
- return {function, file, line};
- }
- };
- std::ostream& operator<<(std::ostream& out, const SourceLocation& loc);
- // unix isprint but insensitive to locale
- inline bool isPrint(char s) {
- return s > 0x1f && s < 0x7f;
- }
- inline void printQuotedString(std::ostream& stmt, const std::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.
- // NOLINTNEXTLINE(*c-arrays*)
- char buf[4] = "000";
- // NOLINTNEXTLINE(*narrowing-conversions)
- buf[2] += s % 8;
- s /= 8;
- // NOLINTNEXTLINE(*narrowing-conversions)
- buf[1] += s % 8;
- s /= 8;
- // NOLINTNEXTLINE(*narrowing-conversions)
- buf[0] += s;
- stmt << "\\" << buf;
- }
- break;
- }
- }
- stmt << '"';
- }
- template <typename T>
- std::optional<T> tryToNumber(const char* symbol) = delete;
- template <typename T>
- std::optional<T> tryToNumber(const std::string& symbol) = delete;
- /*
- * Convert a string to a 64 bit integer. Trailing whitespaces are not supported.
- * Similarly, integer string with trailing characters like "123abc" will be
- * rejected.
- */
- template <>
- C10_API std::optional<int64_t> tryToNumber<int64_t>(const char* symbol);
- template <>
- C10_API std::optional<int64_t> tryToNumber<int64_t>(const std::string& symbol);
- /*
- * Convert a string to a double. Trailing whitespaces are not supported.
- * Similarly, integer string with trailing characters like "123abc" will
- * be rejected.
- */
- template <>
- C10_API std::optional<double> tryToNumber<double>(const char* symbol);
- template <>
- C10_API std::optional<double> tryToNumber<double>(const std::string& symbol);
- C10_API std::vector<std::string_view> split(
- std::string_view target,
- char delimiter);
- } // namespace c10
- C10_CLANG_DIAGNOSTIC_POP()
- #endif // C10_UTIL_STRINGUTIL_H_
- #else
- #error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined."
- #endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION)
|