17
17
#include < ostream>
18
18
#include < string>
19
19
#include < utility>
20
+ #include < variant>
20
21
#include < vector>
21
22
22
23
namespace trpc {
@@ -45,22 +46,8 @@ struct Reply {
45
46
INVALID,
46
47
};
47
48
48
- union Any {
49
- Any () {}
50
- ~Any () {}
51
- Any (std::string&& value) : value_ (std::move (value)) {}
52
- Any (int64_t integer) : integer_ (integer) {}
53
- Any (std::vector<Reply>&& array) : array_ (std::move (array)) {}
54
-
55
- std::string value_;
56
-
57
- int64_t integer_{0 };
58
-
59
- std::vector<Reply> array_;
60
- };
61
-
62
49
Type type_ = Type::NONE;
63
- Any u_;
50
+ std::variant<std::string, int64_t , std::vector<Reply>> u_;
64
51
bool has_value_ = false ;
65
52
uint32_t serial_no_ = 0 ;
66
53
@@ -83,148 +70,70 @@ struct Reply {
83
70
84
71
explicit Reply (InvalidReplyMarker) : type_(Type::INVALID), serial_no_(0 ) {}
85
72
86
- [[gnu::always_inline]] Reply(Reply&& x) noexcept
87
- : type_(x.type_), has_value_(x.has_value_), serial_no_(x.serial_no_) {
88
- switch (type_) {
89
- case Type::NONE:
90
- break ;
91
- case Type::STRING:
92
- case Type::STATUS:
93
- case Type::ERROR:
94
- new (&u_.value_ ) std::basic_string<char >(std::move (x.u_ .value_ ));
95
- x.u_ .value_ .~basic_string ();
96
- break ;
97
- case Type::INTEGER:
98
- u_.integer_ = x.u_ .integer_ ;
99
- break ;
100
- case Type::ARRAY:
101
- new (&u_.array_ ) std::vector<Reply>(std::move (x.u_ .array_ ));
102
- x.u_ .array_ .~vector ();
103
- break ;
104
- case Type::NIL:
105
- case Type::INVALID:
106
- break ;
107
- default :
108
- break ;
109
- }
73
+ Reply (const Reply& x) = default ;
74
+ Reply (Reply&& x) = default ;
110
75
111
- x.type_ = Type::INVALID;
112
- }
113
-
114
- [[gnu::always_inline]] ~Reply () noexcept {
115
- switch (type_) {
116
- case Type::STRING:
117
- case Type::STATUS:
118
- case Type::ERROR:
119
- if (has_value_) {
120
- u_.value_ .~basic_string ();
121
- }
122
- break ;
123
- case Type::INTEGER:
124
- break ;
125
- case Type::ARRAY:
126
- if (has_value_) {
127
- u_.array_ .~vector ();
128
- }
129
- break ;
130
- case Type::NONE:
131
- case Type::NIL:
132
- case Type::INVALID:
133
- break ;
134
- default :
135
- break ;
136
- }
137
- }
138
-
139
- Reply (const Reply& x) noexcept : type_(x.type_), has_value_(x.has_value_), serial_no_(x.serial_no_) {
140
- switch (type_) {
141
- case Type::NONE:
142
- break ;
143
- case Type::STRING:
144
- case Type::STATUS:
145
- case Type::ERROR:
146
- new (&u_.value_ ) std::basic_string<char >(x.u_ .value_ );
147
- break ;
148
- case Type::INTEGER:
149
- u_.integer_ = x.u_ .integer_ ;
150
- break ;
151
- case Type::ARRAY:
152
- new (&u_.array_ ) std::vector<Reply>(x.u_ .array_ );
153
- break ;
154
- case Type::NIL:
155
- case Type::INVALID:
156
- break ;
157
- default :
158
- break ;
159
- }
160
- }
161
-
162
- Reply& operator =(Reply&& x) noexcept {
163
- if (this != &x) {
164
- this ->~Reply ();
165
- new (this ) Reply (std::move (x));
166
- }
167
- return *this ;
168
- }
169
-
170
- Reply& operator =(const Reply& x) noexcept {
171
- if (this != &x) {
172
- this ->~Reply ();
173
- new (this ) Reply (x);
174
- }
175
- return *this ;
176
- }
76
+ Reply& operator =(const Reply& x) = default ;
77
+ Reply& operator =(Reply&& x) = default ;
177
78
178
79
inline void Set (StringReplyMarker, const char * s, size_t len, size_t capacity) {
179
80
has_value_ = true ;
180
- new (&u_.value_ ) std::string ();
181
- u_.value_ .reserve (capacity);
182
- u_.value_ .append (s, len);
81
+ std::string value;
82
+ value.reserve (capacity);
83
+ value.append (s, len);
84
+ u_ = std::move (value);
183
85
}
184
86
185
87
inline void Set (StringReplyMarker, const char * s, size_t len) {
186
88
has_value_ = true ;
187
- new (&u_.value_ ) std::string ();
188
89
if (len < 1 ) {
189
90
return ;
190
91
}
191
- u_.value_ .reserve (len);
192
- u_.value_ .append (s, len);
92
+
93
+ std::string value;
94
+ value.reserve (len);
95
+ value.append (s, len);
96
+ u_ = std::move (value);
193
97
}
194
98
195
99
inline void Set (StatusReplyMarker, const char * s, size_t len, size_t capacity) {
196
100
has_value_ = true ;
197
- new (&u_.value_ ) std::string ();
198
- u_.value_ .reserve (capacity);
199
- u_.value_ .append (s, len);
101
+ std::string value;
102
+ value.reserve (capacity);
103
+ value.append (s, len);
104
+ u_ = std::move (value);
200
105
}
201
106
202
107
inline void Set (StatusReplyMarker, const char * s, size_t len) {
203
108
has_value_ = true ;
204
- new (&u_. value_ ) std::string (s, s + len);
109
+ u_ = std::string (s, s + len);
205
110
}
206
111
207
112
inline void Set (ErrorReplyMarker, const char * s, size_t len, size_t capacity) {
208
113
has_value_ = true ;
209
- new (&u_.value_ ) std::string ();
210
- u_.value_ .reserve (capacity);
211
- u_.value_ .append (s, len);
114
+ std::string value;
115
+ value.reserve (capacity);
116
+ value.append (s, len);
117
+ u_ = std::move (value);
212
118
}
213
119
214
120
inline void Set (ErrorReplyMarker, const char * s, size_t len) {
215
121
has_value_ = true ;
216
- new (&u_. value_ ) std::string (s, s + len);
122
+ u_ = std::string (s, s + len);
217
123
}
218
124
219
- inline void Set (IntegerReplyMarker, int64_t i) { u_. integer_ = i; }
125
+ inline void Set (IntegerReplyMarker, int64_t i) { u_ = i; }
220
126
inline void Set (ArrayReplyMarker) {
221
127
has_value_ = true ;
222
- new (&u_. array_ ) std::vector<Reply>();
128
+ u_ = std::vector<Reply>();
223
129
}
224
130
inline void Set (NilReplyMarker) { type_ = Type::NIL; }
225
131
inline void Set (InvalidReplyMarker) { type_ = Type::INVALID; }
226
132
227
- inline void AppendString (const char * s, size_t len) { u_.value_ .append (s, len); }
133
+ inline void AppendString (const char * s, size_t len) {
134
+ std::string& value = std::get<std::string>(u_);
135
+ value.append (s, len);
136
+ }
228
137
229
138
inline bool IsNone () const { return type_ == Type::NONE; }
230
139
inline bool IsNil () const { return type_ == Type::NIL; }
@@ -236,18 +145,17 @@ struct Reply {
236
145
inline bool IsInvalid () const { return type_ == Type::INVALID; }
237
146
238
147
// / @brief Get reply as string ONLY when type is in[string/status/error]
239
- inline const std::basic_string<char >& GetString () const { return u_. value_ ; }
148
+ inline const std::basic_string<char >& GetString () const { return std::get<std::string>(u_) ; }
240
149
241
- inline int64_t GetInteger () const { return u_. integer_ ; }
242
- inline const std::vector<Reply>& GetArray () const { return u_. array_ ; }
150
+ inline int64_t GetInteger () const { return std::get< int64_t >(u_) ; }
151
+ inline const std::vector<Reply>& GetArray () const { return std::get<std::vector<Reply>>(u_) ; }
243
152
244
153
// / @brief Get reply as string ONLY when type is string when need for high performance
245
154
// / It will use std::move the move this reply,so DO NOT invoke repeatly
246
155
inline int GetString (std::string& value) {
247
156
if (has_value_ && type_ == Type::STRING) {
248
- if (!u_.value_ .empty ()) {
249
- value = std::move (u_.value_ );
250
- }
157
+ value = std::move (std::get<std::string>(u_));
158
+
251
159
has_value_ = false ;
252
160
return 0 ;
253
161
}
@@ -258,9 +166,8 @@ struct Reply {
258
166
// / It will use std::move the move this reply,so DO NOT invoke repeatly
259
167
inline int GetArray (std::vector<Reply>& value) {
260
168
if (has_value_ && type_ == Type::ARRAY) {
261
- if (!u_.array_ .empty ()) {
262
- value = std::move (u_.array_ );
263
- }
169
+ value = std::move (std::get<std::vector<Reply>>(u_));
170
+
264
171
has_value_ = false ;
265
172
return 0 ;
266
173
}
0 commit comments