Line data Source code
1 : // Copyright (c) 2019-2022 The Bitcoin Core developers 2 : // Distributed under the MIT software license, see the accompanying 3 : // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 : 5 : #ifndef BITCOIN_UTIL_STRING_H 6 : #define BITCOIN_UTIL_STRING_H 7 : 8 : #include <util/spanparsing.h> 9 : 10 : #include <array> 11 : #include <cstdint> 12 : #include <cstring> 13 : #include <locale> 14 : #include <sstream> 15 : #include <string> // IWYU pragma: export 16 : #include <string_view> // IWYU pragma: export 17 : #include <vector> 18 : 19 : void ReplaceAll(std::string& in_out, const std::string& search, const std::string& substitute); 20 : 21 364 : [[nodiscard]] inline std::vector<std::string> SplitString(std::string_view str, char sep) 22 : { 23 364 : return spanparsing::Split<std::string>(str, sep); 24 : } 25 : 26 0 : [[nodiscard]] inline std::vector<std::string> SplitString(std::string_view str, std::string_view separators) 27 : { 28 0 : return spanparsing::Split<std::string>(str, separators); 29 : } 30 : 31 1 : [[nodiscard]] inline std::string_view TrimStringView(std::string_view str, std::string_view pattern = " \f\n\r\t\v") 32 : { 33 1 : std::string::size_type front = str.find_first_not_of(pattern); 34 1 : if (front == std::string::npos) { 35 0 : return {}; 36 : } 37 1 : std::string::size_type end = str.find_last_not_of(pattern); 38 1 : return str.substr(front, end - front + 1); 39 1 : } 40 : 41 0 : [[nodiscard]] inline std::string TrimString(std::string_view str, std::string_view pattern = " \f\n\r\t\v") 42 : { 43 0 : return std::string(TrimStringView(str, pattern)); 44 0 : } 45 : 46 1 : [[nodiscard]] inline std::string_view RemovePrefixView(std::string_view str, std::string_view prefix) 47 : { 48 1 : if (str.substr(0, prefix.size()) == prefix) { 49 0 : return str.substr(prefix.size()); 50 : } 51 1 : return str; 52 1 : } 53 : 54 1 : [[nodiscard]] inline std::string RemovePrefix(std::string_view str, std::string_view prefix) 55 : { 56 1 : return std::string(RemovePrefixView(str, prefix)); 57 0 : } 58 : 59 : /** 60 : * Join all container items. Typically used to concatenate strings but accepts 61 : * containers with elements of any type. 62 : * 63 : * @param container The items to join 64 : * @param separator The separator 65 : * @param unary_op Apply this operator to each item 66 : */ 67 : template <typename C, typename S, typename UnaryOp> 68 37 : auto Join(const C& container, const S& separator, UnaryOp unary_op) 69 : { 70 37 : decltype(unary_op(*container.begin())) ret; 71 37 : bool first{true}; 72 371 : for (const auto& item : container) { 73 334 : if (!first) ret += separator; 74 334 : ret += unary_op(item); 75 334 : first = false; 76 : } 77 37 : return ret; 78 37 : } 79 : 80 : template <typename C, typename S> 81 27 : auto Join(const C& container, const S& separator) 82 : { 83 223 : return Join(container, separator, [](const auto& i) { return i; }); 84 : } 85 : 86 : /** 87 : * Create an unordered multi-line list of items. 88 : */ 89 2 : inline std::string MakeUnorderedList(const std::vector<std::string>& items) 90 : { 91 14 : return Join(items, "\n", [](const std::string& item) { return "- " + item; }); 92 : } 93 : 94 : /** 95 : * Check if a string does not contain any embedded NUL (\0) characters 96 : */ 97 0 : [[nodiscard]] inline bool ContainsNoNUL(std::string_view str) noexcept 98 : { 99 0 : for (auto c : str) { 100 0 : if (c == 0) return false; 101 : } 102 0 : return true; 103 0 : } 104 : 105 : /** 106 : * Locale-independent version of std::to_string 107 : */ 108 : template <typename T> 109 5 : std::string ToString(const T& t) 110 : { 111 5 : std::ostringstream oss; 112 5 : oss.imbue(std::locale::classic()); 113 5 : oss << t; 114 5 : return oss.str(); 115 5 : } 116 : 117 : /** 118 : * Check whether a container begins with the given prefix. 119 : */ 120 : template <typename T1, size_t PREFIX_LEN> 121 0 : [[nodiscard]] inline bool HasPrefix(const T1& obj, 122 : const std::array<uint8_t, PREFIX_LEN>& prefix) 123 : { 124 0 : return obj.size() >= PREFIX_LEN && 125 0 : std::equal(std::begin(prefix), std::end(prefix), std::begin(obj)); 126 : } 127 : 128 : #endif // BITCOIN_UTIL_STRING_H