• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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