aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/google/protobuf/arenastring.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/google/protobuf/arenastring.h')
-rwxr-xr-xsrc/google/protobuf/arenastring.h52
1 files changed, 49 insertions, 3 deletions
diff --git a/src/google/protobuf/arenastring.h b/src/google/protobuf/arenastring.h
index 2b108616..168fc972 100755
--- a/src/google/protobuf/arenastring.h
+++ b/src/google/protobuf/arenastring.h
@@ -99,6 +99,13 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr {
if (ptr_ == default_value) {
return NULL;
}
+ return ReleaseNonDefault(default_value, arena);
+ }
+
+ // Similar to Release, but ptr_ cannot be the default_value.
+ inline ::std::string* ReleaseNonDefault(
+ const ::std::string* default_value, ::google::protobuf::Arena* arena) {
+ GOOGLE_DCHECK(!IsDefault(default_value));
::std::string* released = NULL;
if (arena != NULL) {
// ptr_ is owned by the arena.
@@ -164,6 +171,29 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr {
GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE void Swap(ArenaStringPtr* other) {
std::swap(ptr_, other->ptr_);
}
+ GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE void Swap(
+ ArenaStringPtr* other, const ::std::string* default_value, Arena* arena) {
+#ifndef NDEBUG
+ // For debug builds, we swap the contents of the string, rather than the
+ // string instances themselves. This invalidates previously taken const
+ // references that are (per our documentation) invalidated by calling Swap()
+ // on the message.
+ //
+ // If both strings are the default_value, swapping is uninteresting.
+ // Otherwise, we use ArenaStringPtr::Mutable() to access the string, to
+ // ensure that we do not try to mutate default_value itself.
+ if (IsDefault(default_value) && other->IsDefault(default_value)) {
+ return;
+ }
+
+ ::std::string* this_ptr = Mutable(default_value, arena);
+ ::std::string* other_ptr = other->Mutable(default_value, arena);
+
+ this_ptr->swap(*other_ptr);
+#else
+ std::swap(ptr_, other->ptr_);
+#endif
+ }
// Frees storage (if not on an arena).
inline void Destroy(const ::std::string* default_value,
@@ -186,6 +216,15 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr {
}
}
+ // Clears content, assuming that the current value is not the empty string
+ // default.
+ inline void ClearNonDefaultToEmpty() {
+ ptr_->clear();
+ }
+ inline void ClearNonDefaultToEmptyNoArena() {
+ ptr_->clear();
+ }
+
// Clears content, but keeps allocated string if arena != NULL, to avoid the
// overhead of heap operations. After this returns, the content (as seen by
// the user) will always be equal to |default_value|.
@@ -253,12 +292,19 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr {
if (ptr_ == default_value) {
return NULL;
} else {
- ::std::string* released = ptr_;
- ptr_ = const_cast< ::std::string* >(default_value);
- return released;
+ return ReleaseNonDefaultNoArena(default_value);
}
}
+ inline ::std::string* ReleaseNonDefaultNoArena(
+ const ::std::string* default_value) {
+ GOOGLE_DCHECK(!IsDefault(default_value));
+ ::std::string* released = ptr_;
+ ptr_ = const_cast< ::std::string* >(default_value);
+ return released;
+ }
+
+
inline void SetAllocatedNoArena(const ::std::string* default_value,
::std::string* value) {
if (ptr_ != default_value) {