Repository: llvm/llvm-project
File: lldb/include/lldb/Utility/AnsiTerminal.h (C/C++)

Code before:
    str = right;
  }
  return stripped;
}

inline size_t ColumnWidth(llvm::StringRef str) {
  std::string stripped = ansi::StripAnsiTerminalCodes(str);
  return llvm::sys::locale::columnWidth(stripped);
}

/// Trim the given string to the given visible length, at a word boundary.
/// Visible length means its width when rendered to the terminal.
/// The string can include ANSI codes and Unicode.
///
/// For a single word string, that word is returned in its entirety regardless
/// of it's visible length.
///
/// This function is similar to TrimAndPad, except that it must split on a word
/// boundary. So there are some noteable differences:
/// * Has a special case for single words that exceed desired visible
///   length.
/// * Must track whether the most recent modifications was on a word boundary
///   or not.
/// * If the trimming finishes without the result ending on a word boundary,
///   it must find the nearest boundary to that trim point by trimming more.
inline std::string TrimAtWordBoundary(llvm::StringRef str,
                                      size_t visible_length) {
  str = str.trim();
  if (str.empty())
    return str.str();

  auto first_whitespace = str.find_first_of(" \t\n");
  // No whitespace means a single word, which we cannot split.
  if (first_whitespace == llvm::StringRef::npos)
    return str.str();

  // If the first word of a multi-word string is too wide, return that whole
  // word only.
  auto to_first_word_boundary = str.substr(0, first_whitespace);
  // We use ansi::ColumnWidth here because it can handle ANSI and Unicode.
  if (static_cast<size_t>(ansi::ColumnWidth(to_first_word_boundary)) >
      visible_length)
    return to_first_word_boundary.str();

  std::string result;
  result.reserve(visible_length);
  // When there is Unicode or ANSI codes, the visible length will not equal
  // result.size(), so we track it separately.
  size_t result_visible_length = 0;

  // The loop below makes many adjustments, and we never know which will be the

Review comment (suggestion):
I think this could return a StringRef, but that would make it diverge from TrimAndPad more. So I'd prefer to do that in its own change, if this PR is accepted.

It seems like it would work, since TrimAtWordBoundary never needs to add characters. Won't avoid all copies, because we have to do some ANSI removal during the loop.

Code after:
    str = right;
  }
  return stripped;
}

inline size_t ColumnWidth(llvm::StringRef str) {
  std::string stripped = ansi::StripAnsiTerminalCodes(str);
  return llvm::sys::locale::columnWidth(stripped);
}

/// Trim the given string to the given visible length, at a word boundary.
/// Visible length means its width when rendered to the terminal.
/// The string can include ANSI codes and Unicode.
///
/// For a single word string, that word is returned in its entirety regardless
/// of its visible length.
///
/// This function is similar to TrimAndPad, except that it must split on a word
/// boundary. So there are some notable differences:
/// * Has a special case for single words that exceed desired visible
///   length.
/// * Must track whether the most recent modifications was on a word boundary
///   or not.
/// * If the trimming finishes without the result ending on a word boundary,
///   it must find the nearest boundary to that trim point by trimming more.
inline std::string TrimAtWordBoundary(llvm::StringRef str,
                                      size_t visible_length) {
  str = str.trim();
  if (str.empty())
    return str.str();

  auto first_whitespace = str.find_first_of(" \t\n");
  // No whitespace means a single word, which we cannot split.
  if (first_whitespace == llvm::StringRef::npos)
    return str.str();

  // If the first word of a multi-word string is too wide, return that whole
  // word only.
  auto to_first_word_boundary = str.substr(0, first_whitespace);
  // We use ansi::ColumnWidth here because it can handle ANSI and Unicode.
  if (ansi::ColumnWidth(to_first_word_boundary) > visible_length)
    return to_first_word_boundary.str();

  std::string result;
  result.reserve(visible_length);
  // When there is Unicode or ANSI codes, the visible length will not equal
  // result.size(), so we track it separately.
  size_t result_visible_length = 0;

  // The loop below makes many adjustments, and we never know which will be the
  // last. This tracks whether the most recent adjustment put us at a word