strcat.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef BASE_STRINGS_STRCAT_H_
  5. #define BASE_STRINGS_STRCAT_H_
  6. #include <initializer_list>
  7. #include "base/base_export.h"
  8. #include "base/compiler_specific.h"
  9. #include "base/containers/span.h"
  10. #include "base/strings/string_piece.h"
  11. #include "build/build_config.h"
  12. #if defined(OS_WIN)
  13. // Guard against conflict with Win32 API StrCat macro:
  14. // check StrCat wasn't and will not be redefined.
  15. #define StrCat StrCat
  16. #endif
  17. namespace base {
  18. // StrCat ----------------------------------------------------------------------
  19. //
  20. // StrCat is a function to perform concatenation on a sequence of strings.
  21. // It is preferrable to a sequence of "a + b + c" because it is both faster and
  22. // generates less code.
  23. //
  24. // std::string result = base::StrCat({"foo ", result, "\nfoo ", bar});
  25. //
  26. // To join an array of strings with a separator, see base::JoinString in
  27. // base/strings/string_util.h.
  28. //
  29. // MORE INFO
  30. //
  31. // StrCat can see all arguments at once, so it can allocate one return buffer
  32. // of exactly the right size and copy once, as opposed to a sequence of
  33. // operator+ which generates a series of temporary strings, copying as it goes.
  34. // And by using StringPiece arguments, StrCat can avoid creating temporary
  35. // string objects for char* constants.
  36. //
  37. // ALTERNATIVES
  38. //
  39. // Internal Google / Abseil has a similar StrCat function. That version takes
  40. // an overloaded number of arguments instead of initializer list (overflowing
  41. // to initializer list for many arguments). We don't have any legacy
  42. // requirements and using only initializer_list is simpler and generates
  43. // roughly the same amount of code at the call sites.
  44. //
  45. // Abseil's StrCat also allows numbers by using an intermediate class that can
  46. // be implicitly constructed from either a string or various number types. This
  47. // class formats the numbers into a static buffer for increased performance,
  48. // and the call sites look nice.
  49. //
  50. // As-written Abseil's helper class for numbers generates slightly more code
  51. // than the raw StringPiece version. We can de-inline the helper class'
  52. // constructors which will cause the StringPiece constructors to be de-inlined
  53. // for this call and generate slightly less code. This is something we can
  54. // explore more in the future.
  55. BASE_EXPORT std::string StrCat(span<const StringPiece> pieces)
  56. WARN_UNUSED_RESULT;
  57. BASE_EXPORT string16 StrCat(span<const StringPiece16> pieces)
  58. WARN_UNUSED_RESULT;
  59. BASE_EXPORT std::string StrCat(span<const std::string> pieces)
  60. WARN_UNUSED_RESULT;
  61. BASE_EXPORT string16 StrCat(span<const string16> pieces) WARN_UNUSED_RESULT;
  62. // Initializer list forwards to the array version.
  63. inline std::string StrCat(std::initializer_list<StringPiece> pieces) {
  64. return StrCat(make_span(pieces));
  65. }
  66. inline string16 StrCat(std::initializer_list<StringPiece16> pieces) {
  67. return StrCat(make_span(pieces));
  68. }
  69. // StrAppend -------------------------------------------------------------------
  70. //
  71. // Appends a sequence of strings to a destination. Prefer:
  72. // StrAppend(&foo, ...);
  73. // over:
  74. // foo += StrCat(...);
  75. // because it avoids a temporary string allocation and copy.
  76. BASE_EXPORT void StrAppend(std::string* dest, span<const StringPiece> pieces);
  77. BASE_EXPORT void StrAppend(string16* dest, span<const StringPiece16> pieces);
  78. BASE_EXPORT void StrAppend(std::string* dest, span<const std::string> pieces);
  79. BASE_EXPORT void StrAppend(string16* dest, span<const string16> pieces);
  80. // Initializer list forwards to the array version.
  81. inline void StrAppend(std::string* dest,
  82. std::initializer_list<StringPiece> pieces) {
  83. StrAppend(dest, make_span(pieces));
  84. }
  85. inline void StrAppend(string16* dest,
  86. std::initializer_list<StringPiece16> pieces) {
  87. StrAppend(dest, make_span(pieces));
  88. }
  89. } // namespace base
  90. #if defined(OS_WIN)
  91. #include "base/strings/strcat_win.h"
  92. #endif
  93. #endif // BASE_STRINGS_STRCAT_H_