1 // © 2016 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 3 // Copyright (C) 2009-2013, International Business Machines 4 // Corporation and others. All Rights Reserved. 5 // 6 // Copyright 2001 and onwards Google Inc. 7 // Author: Sanjay Ghemawat 8 9 // This code is a contribution of Google code, and the style used here is 10 // a compromise between the original Google code and the ICU coding guidelines. 11 // For example, data types are ICU-ified (size_t,int->int32_t), 12 // and API comments doxygen-ified, but function names and behavior are 13 // as in the original, if possible. 14 // Assertion-style error handling, not available in ICU, was changed to 15 // parameter "pinning" similar to UnicodeString. 16 // 17 // In addition, this is only a partial port of the original Google code, 18 // limited to what was needed so far. The (nearly) complete original code 19 // is in the ICU svn repository at icuhtml/trunk/design/strings/contrib 20 // (see ICU ticket 6765, r25517). 21 22 #ifndef __STRINGPIECE_H__ 23 #define __STRINGPIECE_H__ 24 25 /** 26 * \file 27 * \brief C++ API: StringPiece: Read-only byte string wrapper class. 28 */ 29 30 #include "unicode/utypes.h" 31 32 #if U_SHOW_CPLUSPLUS_API 33 34 #include <cstddef> 35 #include <type_traits> 36 37 #include "unicode/uobject.h" 38 #include "unicode/std_string.h" 39 40 // Arghh! I wish C++ literals were "string". 41 42 U_NAMESPACE_BEGIN 43 44 /** 45 * A string-like object that points to a sized piece of memory. 46 * 47 * We provide non-explicit singleton constructors so users can pass 48 * in a "const char*" or a "string" wherever a "StringPiece" is 49 * expected. 50 * 51 * Functions or methods may use StringPiece parameters to accept either a 52 * "const char*" or a "string" value that will be implicitly converted to a 53 * StringPiece. 54 * 55 * Systematic usage of StringPiece is encouraged as it will reduce unnecessary 56 * conversions from "const char*" to "string" and back again. 57 * 58 * @stable ICU 4.2 59 */ 60 class U_COMMON_API StringPiece : public UMemory { 61 private: 62 const char* ptr_; 63 int32_t length_; 64 65 public: 66 /** 67 * Default constructor, creates an empty StringPiece. 68 * @stable ICU 4.2 69 */ StringPiece()70 StringPiece() : ptr_(NULL), length_(0) { } 71 /** 72 * Constructs from a NUL-terminated const char * pointer. 73 * @param str a NUL-terminated const char * pointer 74 * @stable ICU 4.2 75 */ 76 StringPiece(const char* str); 77 /** 78 * Constructs from a std::string. 79 * @stable ICU 4.2 80 */ StringPiece(const std::string & str)81 StringPiece(const std::string& str) 82 : ptr_(str.data()), length_(static_cast<int32_t>(str.size())) { } 83 #ifndef U_HIDE_DRAFT_API 84 /** 85 * Constructs from some other implementation of a string piece class, from any 86 * C++ record type that has these two methods: 87 * 88 * \code{.cpp} 89 * 90 * struct OtherStringPieceClass { 91 * const char* data(); 92 * size_t size(); 93 * }; 94 * 95 * \endcode 96 * 97 * The other string piece class will typically be std::string_view from C++17 98 * or absl::string_view from Abseil. 99 * 100 * @param str the other string piece 101 * @draft ICU 65 102 */ 103 template <typename T, 104 typename = typename std::enable_if< 105 std::is_same<decltype(T().data()), const char*>::value && 106 std::is_same<decltype(T().size()), size_t>::value>::type> StringPiece(T str)107 StringPiece(T str) 108 : ptr_(str.data()), length_(static_cast<int32_t>(str.size())) {} 109 #endif // U_HIDE_DRAFT_API 110 /** 111 * Constructs from a const char * pointer and a specified length. 112 * @param offset a const char * pointer (need not be terminated) 113 * @param len the length of the string; must be non-negative 114 * @stable ICU 4.2 115 */ StringPiece(const char * offset,int32_t len)116 StringPiece(const char* offset, int32_t len) : ptr_(offset), length_(len) { } 117 /** 118 * Substring of another StringPiece. 119 * @param x the other StringPiece 120 * @param pos start position in x; must be non-negative and <= x.length(). 121 * @stable ICU 4.2 122 */ 123 StringPiece(const StringPiece& x, int32_t pos); 124 /** 125 * Substring of another StringPiece. 126 * @param x the other StringPiece 127 * @param pos start position in x; must be non-negative and <= x.length(). 128 * @param len length of the substring; 129 * must be non-negative and will be pinned to at most x.length() - pos. 130 * @stable ICU 4.2 131 */ 132 StringPiece(const StringPiece& x, int32_t pos, int32_t len); 133 134 /** 135 * Returns the string pointer. May be NULL if it is empty. 136 * 137 * data() may return a pointer to a buffer with embedded NULs, and the 138 * returned buffer may or may not be null terminated. Therefore it is 139 * typically a mistake to pass data() to a routine that expects a NUL 140 * terminated string. 141 * @return the string pointer 142 * @stable ICU 4.2 143 */ data()144 const char* data() const { return ptr_; } 145 /** 146 * Returns the string length. Same as length(). 147 * @return the string length 148 * @stable ICU 4.2 149 */ size()150 int32_t size() const { return length_; } 151 /** 152 * Returns the string length. Same as size(). 153 * @return the string length 154 * @stable ICU 4.2 155 */ length()156 int32_t length() const { return length_; } 157 /** 158 * Returns whether the string is empty. 159 * @return TRUE if the string is empty 160 * @stable ICU 4.2 161 */ empty()162 UBool empty() const { return length_ == 0; } 163 164 /** 165 * Sets to an empty string. 166 * @stable ICU 4.2 167 */ clear()168 void clear() { ptr_ = NULL; length_ = 0; } 169 170 /** 171 * Reset the stringpiece to refer to new data. 172 * @param xdata pointer the new string data. Need not be nul terminated. 173 * @param len the length of the new data 174 * @stable ICU 4.8 175 */ set(const char * xdata,int32_t len)176 void set(const char* xdata, int32_t len) { ptr_ = xdata; length_ = len; } 177 178 /** 179 * Reset the stringpiece to refer to new data. 180 * @param str a pointer to a NUL-terminated string. 181 * @stable ICU 4.8 182 */ 183 void set(const char* str); 184 185 /** 186 * Removes the first n string units. 187 * @param n prefix length, must be non-negative and <=length() 188 * @stable ICU 4.2 189 */ remove_prefix(int32_t n)190 void remove_prefix(int32_t n) { 191 if (n >= 0) { 192 if (n > length_) { 193 n = length_; 194 } 195 ptr_ += n; 196 length_ -= n; 197 } 198 } 199 200 /** 201 * Removes the last n string units. 202 * @param n suffix length, must be non-negative and <=length() 203 * @stable ICU 4.2 204 */ remove_suffix(int32_t n)205 void remove_suffix(int32_t n) { 206 if (n >= 0) { 207 if (n <= length_) { 208 length_ -= n; 209 } else { 210 length_ = 0; 211 } 212 } 213 } 214 215 /** 216 * Maximum integer, used as a default value for substring methods. 217 * @stable ICU 4.2 218 */ 219 static const int32_t npos; // = 0x7fffffff; 220 221 /** 222 * Returns a substring of this StringPiece. 223 * @param pos start position; must be non-negative and <= length(). 224 * @param len length of the substring; 225 * must be non-negative and will be pinned to at most length() - pos. 226 * @return the substring StringPiece 227 * @stable ICU 4.2 228 */ 229 StringPiece substr(int32_t pos, int32_t len = npos) const { 230 return StringPiece(*this, pos, len); 231 } 232 }; 233 234 /** 235 * Global operator == for StringPiece 236 * @param x The first StringPiece to compare. 237 * @param y The second StringPiece to compare. 238 * @return TRUE if the string data is equal 239 * @stable ICU 4.8 240 */ 241 U_EXPORT UBool U_EXPORT2 242 operator==(const StringPiece& x, const StringPiece& y); 243 244 /** 245 * Global operator != for StringPiece 246 * @param x The first StringPiece to compare. 247 * @param y The second StringPiece to compare. 248 * @return TRUE if the string data is not equal 249 * @stable ICU 4.8 250 */ 251 inline UBool operator!=(const StringPiece& x, const StringPiece& y) { 252 return !(x == y); 253 } 254 255 U_NAMESPACE_END 256 257 #endif /* U_SHOW_CPLUSPLUS_API */ 258 259 #endif // __STRINGPIECE_H__ 260