OLD | NEW |
1 // Protocol Buffers - Google's data interchange format | 1 // Protocol Buffers - Google's data interchange format |
2 // Copyright 2008 Google Inc. All rights reserved. | 2 // Copyright 2008 Google Inc. All rights reserved. |
3 // https://developers.google.com/protocol-buffers/ | 3 // https://developers.google.com/protocol-buffers/ |
4 // | 4 // |
5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
7 // met: | 7 // met: |
8 // | 8 // |
9 // * Redistributions of source code must retain the above copyright | 9 // * Redistributions of source code must retain the above copyright |
10 // notice, this list of conditions and the following disclaimer. | 10 // notice, this list of conditions and the following disclaimer. |
(...skipping 19 matching lines...) Expand all Loading... |
30 | 30 |
31 #ifndef GOOGLE_PROTOBUF_ARENASTRING_H__ | 31 #ifndef GOOGLE_PROTOBUF_ARENASTRING_H__ |
32 #define GOOGLE_PROTOBUF_ARENASTRING_H__ | 32 #define GOOGLE_PROTOBUF_ARENASTRING_H__ |
33 | 33 |
34 #include <string> | 34 #include <string> |
35 | 35 |
36 #include <google/protobuf/stubs/logging.h> | 36 #include <google/protobuf/stubs/logging.h> |
37 #include <google/protobuf/stubs/common.h> | 37 #include <google/protobuf/stubs/common.h> |
38 #include <google/protobuf/stubs/fastmem.h> | 38 #include <google/protobuf/stubs/fastmem.h> |
39 #include <google/protobuf/arena.h> | 39 #include <google/protobuf/arena.h> |
40 #include <google/protobuf/generated_message_util.h> | |
41 | 40 |
42 | 41 |
43 | 42 |
44 // This is the implementation of arena string fields written for the open-source | 43 // This is the implementation of arena string fields written for the open-source |
45 // release. The ArenaStringPtr struct below is an internal implementation class | 44 // release. The ArenaStringPtr struct below is an internal implementation class |
46 // and *should not be used* by user code. It is used to collect string | 45 // and *should not be used* by user code. It is used to collect string |
47 // operations together into one place and abstract away the underlying | 46 // operations together into one place and abstract away the underlying |
48 // string-field pointer representation, so that (for example) an alternate | 47 // string-field pointer representation, so that (for example) an alternate |
49 // implementation that knew more about ::std::string's internals could integrate
more | 48 // implementation that knew more about ::std::string's internals could integrate
more |
50 // closely with the arena allocator. | 49 // closely with the arena allocator. |
51 | 50 |
52 namespace google { | 51 namespace google { |
53 namespace protobuf { | 52 namespace protobuf { |
54 namespace internal { | 53 namespace internal { |
55 | 54 |
56 struct LIBPROTOBUF_EXPORT ArenaStringPtr { | 55 struct LIBPROTOBUF_EXPORT ArenaStringPtr { |
57 inline void Set(const ::std::string* default_value, | 56 inline void Set(const ::std::string* default_value, |
58 const ::std::string& value, ::google::protobuf::Arena* arena)
{ | 57 const ::std::string& value, ::google::protobuf::Arena* arena)
{ |
59 if (ptr_ == default_value) { | 58 if (ptr_ == default_value) { |
60 CreateInstance(arena, &value); | 59 CreateInstance(arena, &value); |
61 } else { | 60 } else { |
62 *ptr_ = value; | 61 *ptr_ = value; |
63 } | 62 } |
64 } | 63 } |
65 | 64 |
66 // Basic accessors. | 65 // Basic accessors. |
67 inline const ::std::string& Get(const ::std::string* /* default_value */) cons
t { | 66 inline const ::std::string& Get() const { return *ptr_; } |
68 return *ptr_; | |
69 } | |
70 | 67 |
71 inline ::std::string* Mutable(const ::std::string* default_value, | 68 inline ::std::string* Mutable(const ::std::string* default_value, |
72 ::google::protobuf::Arena* arena) { | 69 ::google::protobuf::Arena* arena) { |
73 if (ptr_ == default_value) { | 70 if (ptr_ == default_value) { |
74 CreateInstance(arena, default_value); | 71 CreateInstance(arena, default_value); |
75 } | 72 } |
76 return ptr_; | 73 return ptr_; |
77 } | 74 } |
78 | 75 |
79 // Release returns a ::std::string* instance that is heap-allocated and is not | 76 // Release returns a ::std::string* instance that is heap-allocated and is not |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 } | 140 } |
144 } | 141 } |
145 | 142 |
146 // Swaps internal pointers. Arena-safety semantics: this is guarded by the | 143 // Swaps internal pointers. Arena-safety semantics: this is guarded by the |
147 // logic in Swap()/UnsafeArenaSwap() at the message level, so this method is | 144 // logic in Swap()/UnsafeArenaSwap() at the message level, so this method is |
148 // 'unsafe' if called directly. | 145 // 'unsafe' if called directly. |
149 GOOGLE_ATTRIBUTE_ALWAYS_INLINE void Swap(ArenaStringPtr* other) { | 146 GOOGLE_ATTRIBUTE_ALWAYS_INLINE void Swap(ArenaStringPtr* other) { |
150 std::swap(ptr_, other->ptr_); | 147 std::swap(ptr_, other->ptr_); |
151 } | 148 } |
152 | 149 |
153 // Frees storage (if not on an arena) and sets field to default value. | 150 // Frees storage (if not on an arena). |
154 inline void Destroy(const ::std::string* default_value, | 151 inline void Destroy(const ::std::string* default_value, |
155 ::google::protobuf::Arena* arena) { | 152 ::google::protobuf::Arena* arena) { |
156 if (arena == NULL && ptr_ != default_value) { | 153 if (arena == NULL && ptr_ != default_value) { |
157 delete ptr_; | 154 delete ptr_; |
158 } | 155 } |
159 ptr_ = const_cast< ::std::string* >(default_value); | |
160 } | 156 } |
161 | 157 |
162 // Clears content, but keeps allocated string if arena != NULL, to avoid the | 158 // Clears content, but keeps allocated string if arena != NULL, to avoid the |
163 // overhead of heap operations. After this returns, the content (as seen by | 159 // overhead of heap operations. After this returns, the content (as seen by |
164 // the user) will always be the empty string. Assumes that |default_value| | 160 // the user) will always be the empty string. Assumes that |default_value| |
165 // is an empty string. | 161 // is an empty string. |
166 inline void ClearToEmpty(const ::std::string* default_value, | 162 inline void ClearToEmpty(const ::std::string* default_value, |
167 ::google::protobuf::Arena* /* arena */) { | 163 ::google::protobuf::Arena* /* arena */) { |
168 if (ptr_ == default_value) { | 164 if (ptr_ == default_value) { |
169 // Already set to default (which is empty) -- do nothing. | 165 // Already set to default (which is empty) -- do nothing. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 // tagged-pointer manipulations to be avoided. | 203 // tagged-pointer manipulations to be avoided. |
208 inline void SetNoArena(const ::std::string* default_value, | 204 inline void SetNoArena(const ::std::string* default_value, |
209 const ::std::string& value) { | 205 const ::std::string& value) { |
210 if (ptr_ == default_value) { | 206 if (ptr_ == default_value) { |
211 CreateInstanceNoArena(&value); | 207 CreateInstanceNoArena(&value); |
212 } else { | 208 } else { |
213 *ptr_ = value; | 209 *ptr_ = value; |
214 } | 210 } |
215 } | 211 } |
216 | 212 |
| 213 #if LANG_CXX11 |
| 214 void SetNoArena(const ::std::string* default_value, ::std::string&& value) { |
| 215 if (IsDefault(default_value)) { |
| 216 ptr_ = new ::std::string(std::move(value)); |
| 217 } else { |
| 218 *ptr_ = std::move(value); |
| 219 } |
| 220 } |
| 221 #endif |
| 222 |
217 void AssignWithDefault(const ::std::string* default_value, ArenaStringPtr valu
e); | 223 void AssignWithDefault(const ::std::string* default_value, ArenaStringPtr valu
e); |
218 | 224 |
219 inline const ::std::string& GetNoArena(const ::std::string* /* default_value *
/) const { | 225 inline const ::std::string& GetNoArena() const { return *ptr_; } |
220 return *ptr_; | |
221 } | |
222 | 226 |
223 ::std::string* MutableNoArena(const ::std::string* default_value); | 227 ::std::string* MutableNoArena(const ::std::string* default_value); |
224 | 228 |
225 inline ::std::string* ReleaseNoArena(const ::std::string* default_value) { | 229 inline ::std::string* ReleaseNoArena(const ::std::string* default_value) { |
226 if (ptr_ == default_value) { | 230 if (ptr_ == default_value) { |
227 return NULL; | 231 return NULL; |
228 } else { | 232 } else { |
229 ::std::string* released = ptr_; | 233 ::std::string* released = ptr_; |
230 ptr_ = const_cast< ::std::string* >(default_value); | 234 ptr_ = const_cast< ::std::string* >(default_value); |
231 return released; | 235 return released; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 } | 268 } |
265 | 269 |
266 // Internal accessor used only at parse time to provide direct access to the | 270 // Internal accessor used only at parse time to provide direct access to the |
267 // raw pointer from the shared parse routine (in the non-arenas case). The | 271 // raw pointer from the shared parse routine (in the non-arenas case). The |
268 // parse routine does the string allocation in order to save code size in the | 272 // parse routine does the string allocation in order to save code size in the |
269 // generated parsing code. | 273 // generated parsing code. |
270 inline ::std::string** UnsafeRawStringPointer() { | 274 inline ::std::string** UnsafeRawStringPointer() { |
271 return &ptr_; | 275 return &ptr_; |
272 } | 276 } |
273 | 277 |
| 278 inline bool IsDefault(const ::std::string* default_value) const { |
| 279 return ptr_ == default_value; |
| 280 } |
| 281 |
274 private: | 282 private: |
275 ::std::string* ptr_; | 283 ::std::string* ptr_; |
276 | 284 |
277 GOOGLE_ATTRIBUTE_NOINLINE void CreateInstance(::google::protobuf::Arena* arena
, | 285 GOOGLE_ATTRIBUTE_NOINLINE void CreateInstance(::google::protobuf::Arena* arena
, |
278 const ::std::string* initial_value) { | 286 const ::std::string* initial_value) { |
279 // Assumes ptr_ is not NULL. | 287 GOOGLE_DCHECK(initial_value != NULL); |
280 if (initial_value != NULL) { | 288 ptr_ = new ::std::string(*initial_value); |
281 ptr_ = new ::std::string(*initial_value); | |
282 } else { | |
283 ptr_ = new ::std::string(); | |
284 } | |
285 if (arena != NULL) { | 289 if (arena != NULL) { |
286 arena->Own(ptr_); | 290 arena->Own(ptr_); |
287 } | 291 } |
288 } | 292 } |
289 GOOGLE_ATTRIBUTE_NOINLINE void CreateInstanceNoArena(const ::std::string* init
ial_value) { | 293 GOOGLE_ATTRIBUTE_NOINLINE void CreateInstanceNoArena(const ::std::string* init
ial_value) { |
290 if (initial_value != NULL) { | 294 GOOGLE_DCHECK(initial_value != NULL); |
291 ptr_ = new ::std::string(*initial_value); | 295 ptr_ = new ::std::string(*initial_value); |
292 } else { | |
293 ptr_ = new ::std::string(); | |
294 } | |
295 } | 296 } |
296 }; | 297 }; |
297 | 298 |
298 } // namespace internal | 299 } // namespace internal |
299 } // namespace protobuf | 300 } // namespace protobuf |
300 | 301 |
301 | 302 |
302 | 303 |
303 } // namespace google | 304 } // namespace google |
304 #endif // GOOGLE_PROTOBUF_ARENASTRING_H__ | 305 #endif // GOOGLE_PROTOBUF_ARENASTRING_H__ |
OLD | NEW |