Line data Source code
1 : // Copyright (c) 2019-2021 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> 16 : #include <string_view> 17 : #include <vector> 18 : 19 : void ReplaceAll(std::string& in_out, const std::string& search, const std::string& substitute); 20 : 21 3700209 : [[nodiscard]] inline std::vector<std::string> SplitString(std::string_view str, char sep) 22 : { 23 3700209 : return spanparsing::Split<std::string>(str, sep); 24 : } 25 : 26 3366 : [[nodiscard]] inline std::vector<std::string> SplitString(std::string_view str, std::string_view separators) 27 : { 28 3366 : return spanparsing::Split<std::string>(str, separators); 29 : } 30 : 31 3719940 : [[nodiscard]] inline std::string_view TrimStringView(std::string_view str, std::string_view pattern = " \f\n\r\t\v") 32 : { 33 3719940 : std::string::size_type front = str.find_first_not_of(pattern); 34 3719940 : if (front == std::string::npos) { 35 133 : return {}; 36 : } 37 3719807 : std::string::size_type end = str.find_last_not_of(pattern); 38 3719807 : return str.substr(front, end - front + 1); 39 3719940 : } 40 : 41 398035 : [[nodiscard]] inline std::string TrimString(std::string_view str, std::string_view pattern = " \f\n\r\t\v") 42 : { 43 398035 : return std::string(TrimStringView(str, pattern)); 44 : } 45 : 46 26341519 : [[nodiscard]] inline std::string_view RemovePrefixView(std::string_view str, std::string_view prefix) 47 : { 48 26341519 : if (str.substr(0, prefix.size()) == prefix) { 49 6 : return str.substr(prefix.size()); 50 : } 51 26341513 : return str; 52 26341519 : } 53 : 54 26341515 : [[nodiscard]] inline std::string RemovePrefix(std::string_view str, std::string_view prefix) 55 : { 56 26341515 : return std::string(RemovePrefixView(str, prefix)); 57 : } 58 : 59 7 : [[nodiscard]] inline std::string PadString(std::string str, std::string::size_type size, bool left = true) 60 : { 61 7 : if (size <= str.size()) return str; 62 4 : return left ? std::string(size - str.size(), ' ').append(str) : str.append(std::string(size - str.size(), ' ')); 63 7 : } 64 : 65 : /** 66 : * Join all container items. Typically used to concatenate strings but accepts 67 : * containers with elements of any type. 68 : * 69 : * @param container The items to join 70 : * @param separator The separator 71 : * @param unary_op Apply this operator to each item 72 : */ 73 : template <typename C, typename S, typename UnaryOp> 74 270998 : auto Join(const C& container, const S& separator, UnaryOp unary_op) 75 : { 76 270998 : decltype(unary_op(*container.begin())) ret; 77 270998 : bool first{true}; 78 2310364 : for (const auto& item : container) { 79 2039366 : if (!first) ret += separator; 80 2039366 : ret += unary_op(item); 81 2039366 : first = false; 82 : } 83 270998 : return ret; 84 270998 : } 85 : 86 : template <typename C, typename S> 87 198370 : auto Join(const C& container, const S& separator) 88 : { 89 1272147 : return Join(container, separator, [](const auto& i) { return i; }); 90 : } 91 : 92 : /** 93 : * Create an unordered multi-line list of items. 94 : */ 95 6166 : inline std::string MakeUnorderedList(const std::vector<std::string>& items) 96 : { 97 43132 : return Join(items, "\n", [](const std::string& item) { return "- " + item; }); 98 : } 99 : 100 : /** 101 : * Check if a string does not contain any embedded NUL (\0) characters 102 : */ 103 7486457 : [[nodiscard]] inline bool ContainsNoNUL(std::string_view str) noexcept 104 : { 105 121292654 : for (auto c : str) { 106 113806219 : if (c == 0) return false; 107 : } 108 7486435 : return true; 109 7486457 : } 110 : 111 : /** 112 : * Check whether a container begins with the given prefix. 113 : */ 114 : template <typename T1, size_t PREFIX_LEN> 115 7940122 : [[nodiscard]] inline bool HasPrefix(const T1& obj, 116 : const std::array<uint8_t, PREFIX_LEN>& prefix) 117 : { 118 15880246 : return obj.size() >= PREFIX_LEN && 119 7940124 : std::equal(std::begin(prefix), std::end(prefix), std::begin(obj)); 120 : } 121 : 122 : /** 123 : * Locale-independent version of std::to_string 124 : */ 125 : template <typename T> 126 26610552 : std::string ToString(const T& t) 127 : { 128 26610552 : std::ostringstream oss; 129 26610552 : oss.imbue(std::locale::classic()); 130 26610552 : oss << t; 131 26610553 : return oss.str(); 132 26610554 : } 133 : 134 : #endif // BITCOIN_UTIL_STRING_H