1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31 #ifndef GOOGLE_PROTOBUF_INLINED_STRING_FIELD_H__
32 #define GOOGLE_PROTOBUF_INLINED_STRING_FIELD_H__
33
34 #include <string>
35 #include <utility>
36
37 #include <google/protobuf/port.h>
38 #include <google/protobuf/stubs/strutil.h>
39
40 // Must be included last.
41 #include <google/protobuf/port_def.inc>
42
43 #ifdef SWIG
44 #error "You cannot SWIG proto headers"
45 #endif
46
47 namespace google {
48 namespace protobuf {
49
50 class Arena;
51
52 namespace internal {
53
54 // InlinedStringField wraps a std::string instance and exposes an API similar to
55 // ArenaStringPtr's wrapping of a std::string* instance. As std::string is
56 // never allocated on the Arena, we expose only the *NoArena methods of
57 // ArenaStringPtr.
58 //
59 // default_value parameters are taken for consistency with ArenaStringPtr, but
60 // are not used for most methods. With inlining, these should be removed from
61 // the generated binary.
62 class PROTOBUF_EXPORT InlinedStringField {
63 public:
64 InlinedStringField() PROTOBUF_ALWAYS_INLINE;
65 explicit InlinedStringField(const std::string& default_value);
66
67 void AssignWithDefault(const std::string* default_value,
68 const InlinedStringField& from) PROTOBUF_ALWAYS_INLINE;
69
ClearToEmpty(const std::string * default_value,Arena *)70 void ClearToEmpty(const std::string* default_value,
71 Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE {
72 ClearToEmptyNoArena(default_value);
73 }
ClearNonDefaultToEmpty()74 void ClearNonDefaultToEmpty() PROTOBUF_ALWAYS_INLINE {
75 ClearNonDefaultToEmptyNoArena();
76 }
ClearToEmptyNoArena(const std::string *)77 void ClearToEmptyNoArena(const std::string* /*default_value*/)
78 PROTOBUF_ALWAYS_INLINE {
79 ClearNonDefaultToEmptyNoArena();
80 }
81 void ClearNonDefaultToEmptyNoArena() PROTOBUF_ALWAYS_INLINE;
82
ClearToDefault(const std::string * default_value,Arena *)83 void ClearToDefault(const std::string* default_value,
84 Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE {
85 ClearToDefaultNoArena(default_value);
86 }
87 void ClearToDefaultNoArena(const std::string* default_value)
88 PROTOBUF_ALWAYS_INLINE;
89
Destroy(const std::string * default_value,Arena *)90 void Destroy(const std::string* default_value,
91 Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE {
92 DestroyNoArena(default_value);
93 }
94 void DestroyNoArena(const std::string* default_value) PROTOBUF_ALWAYS_INLINE;
95
Get()96 const std::string& Get() const PROTOBUF_ALWAYS_INLINE { return GetNoArena(); }
97 const std::string& GetNoArena() const PROTOBUF_ALWAYS_INLINE;
98
Mutable(const std::string * default_value,Arena *)99 std::string* Mutable(const std::string* default_value,
100 Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE {
101 return MutableNoArena(default_value);
102 }
103 std::string* MutableNoArena(const std::string* default_value)
104 PROTOBUF_ALWAYS_INLINE;
105
Release(const std::string * default_value,Arena *)106 std::string* Release(const std::string* default_value, Arena* /*arena*/) {
107 return ReleaseNoArena(default_value);
108 }
ReleaseNonDefault(const std::string * default_value,Arena *)109 std::string* ReleaseNonDefault(const std::string* default_value,
110 Arena* /*arena*/) {
111 return ReleaseNonDefaultNoArena(default_value);
112 }
ReleaseNoArena(const std::string * default_value)113 std::string* ReleaseNoArena(const std::string* default_value) {
114 return ReleaseNonDefaultNoArena(default_value);
115 }
116 std::string* ReleaseNonDefaultNoArena(const std::string* default_value);
117
Set(const std::string * default_value,StringPiece value,Arena *)118 void Set(const std::string* default_value, StringPiece value,
119 Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE {
120 SetNoArena(default_value, value);
121 }
SetLite(const std::string * default_value,StringPiece value,Arena *)122 void SetLite(const std::string* default_value, StringPiece value,
123 Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE {
124 SetNoArena(default_value, value);
125 }
126 void SetNoArena(const std::string* default_value,
127 StringPiece value) PROTOBUF_ALWAYS_INLINE;
128
Set(const std::string * default_value,const std::string & value,Arena *)129 void Set(const std::string* default_value, const std::string& value,
130 Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE {
131 SetNoArena(default_value, value);
132 }
SetLite(const std::string * default_value,const std::string & value,Arena *)133 void SetLite(const std::string* default_value, const std::string& value,
134 Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE {
135 SetNoArena(default_value, value);
136 }
137 void SetNoArena(const std::string* default_value,
138 const std::string& value) PROTOBUF_ALWAYS_INLINE;
139
140 void SetNoArena(const std::string* default_value,
141 std::string&& value) PROTOBUF_ALWAYS_INLINE;
SetAllocated(const std::string * default_value,std::string * value,Arena *)142 void SetAllocated(const std::string* default_value, std::string* value,
143 Arena* /*arena*/) {
144 SetAllocatedNoArena(default_value, value);
145 }
146 void SetAllocatedNoArena(const std::string* default_value,
147 std::string* value);
148 void Swap(InlinedStringField* from) PROTOBUF_ALWAYS_INLINE;
149 std::string* UnsafeMutablePointer();
150 void UnsafeSetDefault(const std::string* default_value);
151 std::string* UnsafeArenaRelease(const std::string* default_value,
152 Arena* arena);
153 void UnsafeArenaSetAllocated(const std::string* default_value,
154 std::string* value, Arena* arena);
155
IsDefault(const std::string *)156 bool IsDefault(const std::string* /*default_value*/) { return false; }
157
158 private:
159 std::string value_;
160 };
161
InlinedStringField()162 inline InlinedStringField::InlinedStringField() {}
163
InlinedStringField(const std::string & default_value)164 inline InlinedStringField::InlinedStringField(const std::string& default_value)
165 : value_(default_value) {}
166
AssignWithDefault(const std::string *,const InlinedStringField & from)167 inline void InlinedStringField::AssignWithDefault(
168 const std::string* /*default_value*/, const InlinedStringField& from) {
169 value_ = from.value_;
170 }
171
GetNoArena()172 inline const std::string& InlinedStringField::GetNoArena() const {
173 return value_;
174 }
175
MutableNoArena(const std::string *)176 inline std::string* InlinedStringField::MutableNoArena(const std::string*) {
177 return &value_;
178 }
179
SetAllocatedNoArena(const std::string * default_value,std::string * value)180 inline void InlinedStringField::SetAllocatedNoArena(
181 const std::string* default_value, std::string* value) {
182 if (value == NULL) {
183 value_.assign(*default_value);
184 } else {
185 value_.assign(std::move(*value));
186 delete value;
187 }
188 }
189
DestroyNoArena(const std::string *)190 inline void InlinedStringField::DestroyNoArena(const std::string*) {
191 // This is invoked from the generated message's ArenaDtor, which is used to
192 // clean up objects not allocated on the Arena.
193 this->~InlinedStringField();
194 }
195
ClearNonDefaultToEmptyNoArena()196 inline void InlinedStringField::ClearNonDefaultToEmptyNoArena() {
197 value_.clear();
198 }
199
ClearToDefaultNoArena(const std::string * default_value)200 inline void InlinedStringField::ClearToDefaultNoArena(
201 const std::string* default_value) {
202 value_.assign(*default_value);
203 }
204
ReleaseNonDefaultNoArena(const std::string * default_value)205 inline std::string* InlinedStringField::ReleaseNonDefaultNoArena(
206 const std::string* default_value) {
207 std::string* released = new std::string(*default_value);
208 value_.swap(*released);
209 return released;
210 }
211
SetNoArena(const std::string *,StringPiece value)212 inline void InlinedStringField::SetNoArena(const std::string* /*default_value*/,
213 StringPiece value) {
214 value_.assign(value.data(), value.length());
215 }
216
SetNoArena(const std::string *,const std::string & value)217 inline void InlinedStringField::SetNoArena(const std::string* /*default_value*/,
218 const std::string& value) {
219 value_.assign(value);
220 }
221
SetNoArena(const std::string *,std::string && value)222 inline void InlinedStringField::SetNoArena(const std::string* /*default_value*/,
223 std::string&& value) {
224 value_.assign(std::move(value));
225 }
226
Swap(InlinedStringField * from)227 inline void InlinedStringField::Swap(InlinedStringField* from) {
228 value_.swap(from->value_);
229 }
230
UnsafeMutablePointer()231 inline std::string* InlinedStringField::UnsafeMutablePointer() {
232 return &value_;
233 }
234
UnsafeSetDefault(const std::string * default_value)235 inline void InlinedStringField::UnsafeSetDefault(
236 const std::string* default_value) {
237 value_.assign(*default_value);
238 }
239
UnsafeArenaRelease(const std::string * default_value,Arena *)240 inline std::string* InlinedStringField::UnsafeArenaRelease(
241 const std::string* default_value, Arena* /*arena*/) {
242 return ReleaseNoArena(default_value);
243 }
244
UnsafeArenaSetAllocated(const std::string * default_value,std::string * value,Arena *)245 inline void InlinedStringField::UnsafeArenaSetAllocated(
246 const std::string* default_value, std::string* value, Arena* /*arena*/) {
247 if (value == NULL) {
248 value_.assign(*default_value);
249 } else {
250 value_.assign(*value);
251 }
252 }
253
254 } // namespace internal
255 } // namespace protobuf
256 } // namespace google
257
258 #include <google/protobuf/port_undef.inc>
259
260 #endif // GOOGLE_PROTOBUF_INLINED_STRING_FIELD_H__
261