@@ -136,7 +136,8 @@ constexpr bool is_crubit_abi = requires {
136136 // };
137137 // ```
138138 {
139- Abi::Encode (std::declval<typename Abi::Value>(), std::declval<Encoder&>())
139+ std::declval<Abi&&>().Encode (std::declval<typename Abi::Value>(),
140+ std::declval<Encoder&>())
140141 } -> std::same_as<void >;
141142
142143 // Decodes a [`Value`], advancing the decoder's position by `kSize` bytes.
@@ -171,27 +172,19 @@ constexpr bool is_crubit_abi = requires {
171172 // The caller guarantees that the buffer's current position contains a
172173 // `Value` that was encoded with this ABI (either from Rust or C++).
173174 {
174- Abi:: Decode (std::declval<Decoder&>())
175+ std::declval<Abi&&>(). Decode (std::declval<Decoder&>())
175176 } -> std::same_as<typename Abi::Value>;
176177};
177178
178179namespace internal {
179180
180181template <typename Abi>
181182 requires (is_crubit_abi<Abi>)
182- void Encode (unsigned char * buf, typename Abi::Value value);
183+ void Encode (Abi&& abi, unsigned char * buf, typename Abi::Value value);
183184
184185template <typename Abi>
185186 requires (is_crubit_abi<Abi>)
186- void Encode (Abi&&, unsigned char * buf, typename Abi::Value value);
187-
188- template <typename Abi>
189- requires (is_crubit_abi<Abi>)
190- typename Abi::Value Decode (const unsigned char * buf);
191-
192- template <typename Abi>
193- requires (is_crubit_abi<Abi>)
194- typename Abi::Value Decode (Abi&&, const unsigned char * buf);
187+ typename Abi::Value Decode (Abi&& abi, const unsigned char * buf);
195188
196189} // namespace internal
197190
@@ -202,17 +195,6 @@ class Encoder {
202195 : remaining_bytes_(remaining_bytes), buf_(buf) {}
203196
204197 public:
205- // Encodes a value by a provided schema.
206- template <typename Abi>
207- requires (is_crubit_abi<Abi>)
208- void Encode (typename Abi::Value value) & {
209- Abi::Encode (std::move (value), *this );
210- }
211-
212- // Encodes a value via `memcpy`.
213- template <typename T>
214- void EncodeTransmute (T value) &;
215-
216198 void * Next (size_t size) & {
217199 remaining_bytes_ -= size;
218200 return buf_ + remaining_bytes_;
@@ -221,11 +203,7 @@ class Encoder {
221203 private:
222204 template <typename Abi>
223205 requires (is_crubit_abi<Abi>)
224- friend void internal::Encode (unsigned char * buf, typename Abi::Value value);
225-
226- template <typename Abi>
227- requires (is_crubit_abi<Abi>)
228- friend void internal::Encode (Abi&&, unsigned char * buf,
206+ friend void internal::Encode (Abi&& abi, unsigned char * buf,
229207 typename Abi::Value value);
230208 // The number of bytes remaining in the buffer.
231209 size_t remaining_bytes_;
@@ -239,19 +217,6 @@ class Decoder {
239217 : remaining_bytes_(remaining_bytes), buf_(buf) {}
240218
241219 public:
242- // Decodes a value by a provided schema. The caller must ensure that the
243- // buffer contains a value that was encoded with the same schema.
244- template <typename Abi>
245- requires (is_crubit_abi<Abi>)
246- typename Abi::Value Decode () & {
247- return Abi::Decode (*this );
248- }
249-
250- // Decodes a value via `memcpy`. The caller must ensure that the buffer
251- // contains a value that was encoded with ByTransmute.
252- template <typename T>
253- T DecodeTransmute () &;
254-
255220 const void * Next (size_t size) & {
256221 remaining_bytes_ -= size;
257222 return buf_ + remaining_bytes_;
@@ -260,10 +225,8 @@ class Decoder {
260225 private:
261226 template <typename Abi>
262227 requires (is_crubit_abi<Abi>)
263- friend typename Abi::Value internal::Decode (const unsigned char * buf);
264- template <typename Abi>
265- requires (is_crubit_abi<Abi>)
266- friend typename Abi::Value internal::Decode (Abi&&, const unsigned char * buf);
228+ friend typename Abi::Value internal::Decode (Abi&& abi,
229+ const unsigned char * buf);
267230 // The number of bytes remaining in the buffer.
268231 size_t remaining_bytes_;
269232 const unsigned char * buf_;
@@ -276,7 +239,7 @@ template <typename T>
276239struct TransmuteAbi {
277240 using Value = T;
278241 static constexpr size_t kSize = sizeof (Value);
279- static void Encode (Value value, Encoder& encoder) {
242+ void Encode (Value value, Encoder& encoder) && {
280243 // Move-construct the value into a type erased buffer, ensuring that value
281244 // is in a "moved from" state. Then copy the value into the encoder buffer.
282245 // We use an intermediate buffer and a memcpy to avoid strict aliasing
@@ -285,7 +248,7 @@ struct TransmuteAbi {
285248 alignas (Value) char buf[kSize ];
286249 std::memcpy (encoder.Next (kSize ), new (buf) Value (std::move (value)), kSize );
287250 }
288- static Value Decode (Decoder& decoder) {
251+ Value Decode (Decoder& decoder) && {
289252 alignas (Value) char buf[kSize ];
290253 // Copy the value from the decoder buffer into the intermediate buffer.
291254 std::memcpy (buf, decoder.Next (kSize ), kSize );
@@ -294,30 +257,26 @@ struct TransmuteAbi {
294257 }
295258};
296259
297- template <typename T>
298- void Encoder::EncodeTransmute (T value) & {
299- TransmuteAbi<T>::Encode (std::move (value), *this );
300- }
301-
302- template <typename T>
303- T Decoder::DecodeTransmute () & {
304- return TransmuteAbi<T>::Decode (*this );
305- }
306-
307260template <typename ... Abis>
308261 requires (is_crubit_abi<Abis> && ...)
309262struct TupleAbi {
310263 using Value = std::tuple<typename Abis::Value...>;
311264 static constexpr size_t kSize = (0 + ... + Abis::kSize );
312- static void Encode (Value value, Encoder& encoder) {
265+ void Encode (Value value, Encoder& encoder) && {
313266 std::apply (
314- [&](typename Abis::Value&&... args) {
315- (encoder.Encode <Abis>(args), ...);
267+ [&](auto &&... args) {
268+ return std::apply (
269+ [&](auto &&... abis) { (abis.Encode (args..., encoder), ...); },
270+ std::move (abis));
316271 },
317272 std::move (value));
318273 }
319- static Value Decode (Decoder& decoder) {
320- return std::make_tuple (decoder.Decode <Abis>()...);
274+ Value Decode (Decoder& decoder) && {
275+ return std::apply (
276+ [&](Abis&&... abis) {
277+ return std::make_tuple (abis.Decode (decoder)...);
278+ },
279+ std::move (abis));
321280 }
322281
323282 std::tuple<Abis...> abis;
@@ -330,14 +289,14 @@ struct PairAbi {
330289
331290 using Value = std::pair<typename Abi1::Value, typename Abi2::Value>;
332291 static constexpr size_t kSize = Abi1::kSize + Abi2::kSize ;
333- static void Encode (Value value, Encoder& encoder) {
334- encoder. Encode <Abi1> (std::move (value.first ));
335- encoder. Encode <Abi2> (std::move (value.second ));
292+ void Encode (Value value, Encoder& encoder) && {
293+ std::move (abis. first ). Encode (std::move (value.first ), encoder );
294+ std::move (abis. second ). Encode (std::move (value.second ), encoder );
336295 }
337- static Value Decode (Decoder& decoder) {
296+ Value Decode (Decoder& decoder) && {
338297 return {
339- .first = decoder. Decode <Abi1>( ),
340- .second = decoder. Decode <Abi2>( ),
298+ .first = std::move (abis. first ). Decode (decoder ),
299+ .second = std::move (abis. second ). Decode (decoder ),
341300 };
342301 }
343302
@@ -352,19 +311,19 @@ template <typename Abi>
352311struct OptionAbi {
353312 using Value = std::optional<typename Abi::Value>;
354313 static constexpr size_t kSize = sizeof (bool ) + Abi::kSize ;
355- static void Encode (Value value, Encoder& encoder) {
314+ void Encode (Value value, Encoder& encoder) && {
356315 if (value.has_value ()) {
357- encoder. EncodeTransmute (true );
358- encoder .Encode <Abi> (*std::move (value));
316+ TransmuteAbi< bool >(). Encode (true , encoder );
317+ std::move (abi) .Encode (*std::move (value), encoder );
359318 } else {
360- encoder. EncodeTransmute (false );
319+ TransmuteAbi< bool >(). Encode (false , encoder );
361320 }
362321 }
363- static Value Decode (Decoder& decoder) {
364- if (!decoder. DecodeTransmute <bool >()) {
322+ Value Decode (Decoder& decoder) && {
323+ if (!TransmuteAbi <bool >(). Decode (decoder )) {
365324 return std::nullopt ;
366325 }
367- return decoder .Decode <Abi>( );
326+ return abi .Decode (decoder );
368327 }
369328
370329 Abi abi;
@@ -379,12 +338,13 @@ template <typename T>
379338struct BoxedAbi {
380339 using Value = T;
381340 static constexpr size_t kSize = sizeof (void *);
382- static void Encode (Value value, Encoder& encoder) {
341+ void Encode (Value value, Encoder& encoder) && {
383342 void * box = new Value (std::move (value));
384- encoder. EncodeTransmute (box);
343+ TransmuteAbi< void *>(). Encode (box, encoder );
385344 }
386- static Value Decode (Decoder& decoder) {
387- Value* box = reinterpret_cast <Value*>(decoder.DecodeTransmute <void *>());
345+ Value Decode (Decoder& decoder) && {
346+ Value* box =
347+ reinterpret_cast <Value*>(TransmuteAbi<void *>().Decode (decoder));
388348 Value value (std::move (*box));
389349 delete box;
390350 return value;
@@ -395,34 +355,16 @@ namespace internal {
395355
396356template <typename Abi>
397357 requires (is_crubit_abi<Abi>)
398- void Encode (unsigned char * buf, typename Abi::Value value) {
358+ void Encode (Abi&& abi, unsigned char * buf, typename Abi::Value value) {
399359 Encoder encoder (Abi::kSize , buf);
400- encoder.Encode <Abi>(std::move (value));
401- }
402-
403- // TODO(okabayashi): Overload for new Crubit codegen, where an instance of the
404- // ABI is passed in. After the new codegen hits crosstool release, I will delete
405- // other other overload and change the implementation here.
406- template <typename Abi>
407- requires (is_crubit_abi<Abi>)
408- void Encode (Abi&&, unsigned char * buf, typename Abi::Value value) {
409- Encode<Abi>(buf, std::move (value));
360+ std::forward<Abi>(abi).Encode (std::move (value), encoder);
410361}
411362
412363template <typename Abi>
413364 requires (is_crubit_abi<Abi>)
414- typename Abi::Value Decode (const unsigned char * buf) {
365+ typename Abi::Value Decode (Abi&& abi, const unsigned char * buf) {
415366 Decoder decoder (Abi::kSize , buf);
416- return decoder.Decode <Abi>();
417- }
418-
419- // TODO(okabayashi): Overload for new Crubit codegen, where an instance of the
420- // ABI is passed in. After the new codegen hits crosstool release, I will delete
421- // other other overload and change the implementation here.
422- template <typename Abi>
423- requires (is_crubit_abi<Abi>)
424- typename Abi::Value Decode (Abi&&, const unsigned char * buf) {
425- return Decode<Abi>(buf);
367+ return std::forward<Abi>(abi).Decode (decoder);
426368}
427369
428370} // namespace internal
0 commit comments