xref: /netbsd-src/external/apache2/llvm/dist/llvm/include/llvm/ExecutionEngine/Orc/Shared/Serialization.h (revision 82d56013d7b633d116a93943de88e08335357a7c)
1 //===- Serialization.h ------------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_SERIALIZATION_H
10 #define LLVM_EXECUTIONENGINE_ORC_SHARED_SERIALIZATION_H
11 
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/ADT/DenseMap.h"
14 #include "llvm/ExecutionEngine/Orc/Shared/OrcError.h"
15 #include "llvm/Support/thread.h"
16 #include <map>
17 #include <mutex>
18 #include <set>
19 #include <sstream>
20 #include <string>
21 #include <vector>
22 
23 namespace llvm {
24 namespace orc {
25 namespace shared {
26 
27 template <typename T> class SerializationTypeName;
28 
29 /// TypeNameSequence is a utility for rendering sequences of types to a string
30 /// by rendering each type, separated by ", ".
31 template <typename... ArgTs> class SerializationTypeNameSequence {};
32 
33 /// Render an empty TypeNameSequence to an ostream.
34 template <typename OStream>
35 OStream &operator<<(OStream &OS, const SerializationTypeNameSequence<> &V) {
36   return OS;
37 }
38 
39 /// Render a TypeNameSequence of a single type to an ostream.
40 template <typename OStream, typename ArgT>
41 OStream &operator<<(OStream &OS, const SerializationTypeNameSequence<ArgT> &V) {
42   OS << SerializationTypeName<ArgT>::getName();
43   return OS;
44 }
45 
46 /// Render a TypeNameSequence of more than one type to an ostream.
47 template <typename OStream, typename ArgT1, typename ArgT2, typename... ArgTs>
48 OStream &
49 operator<<(OStream &OS,
50            const SerializationTypeNameSequence<ArgT1, ArgT2, ArgTs...> &V) {
51   OS << SerializationTypeName<ArgT1>::getName() << ", "
52      << SerializationTypeNameSequence<ArgT2, ArgTs...>();
53   return OS;
54 }
55 
56 template <> class SerializationTypeName<void> {
57 public:
getName()58   static const char *getName() { return "void"; }
59 };
60 
61 template <> class SerializationTypeName<int8_t> {
62 public:
getName()63   static const char *getName() { return "int8_t"; }
64 };
65 
66 template <> class SerializationTypeName<uint8_t> {
67 public:
getName()68   static const char *getName() { return "uint8_t"; }
69 };
70 
71 template <> class SerializationTypeName<int16_t> {
72 public:
getName()73   static const char *getName() { return "int16_t"; }
74 };
75 
76 template <> class SerializationTypeName<uint16_t> {
77 public:
getName()78   static const char *getName() { return "uint16_t"; }
79 };
80 
81 template <> class SerializationTypeName<int32_t> {
82 public:
getName()83   static const char *getName() { return "int32_t"; }
84 };
85 
86 template <> class SerializationTypeName<uint32_t> {
87 public:
getName()88   static const char *getName() { return "uint32_t"; }
89 };
90 
91 template <> class SerializationTypeName<int64_t> {
92 public:
getName()93   static const char *getName() { return "int64_t"; }
94 };
95 
96 template <> class SerializationTypeName<uint64_t> {
97 public:
getName()98   static const char *getName() { return "uint64_t"; }
99 };
100 
101 template <> class SerializationTypeName<bool> {
102 public:
getName()103   static const char *getName() { return "bool"; }
104 };
105 
106 template <> class SerializationTypeName<std::string> {
107 public:
getName()108   static const char *getName() { return "std::string"; }
109 };
110 
111 template <> class SerializationTypeName<Error> {
112 public:
getName()113   static const char *getName() { return "Error"; }
114 };
115 
116 template <typename T> class SerializationTypeName<Expected<T>> {
117 public:
getName()118   static const char *getName() {
119     static std::string Name = [] {
120       std::string Name;
121       raw_string_ostream(Name)
122           << "Expected<" << SerializationTypeNameSequence<T>() << ">";
123       return Name;
124     }();
125     return Name.data();
126   }
127 };
128 
129 template <typename T1, typename T2>
130 class SerializationTypeName<std::pair<T1, T2>> {
131 public:
getName()132   static const char *getName() {
133     static std::string Name = [] {
134       std::string Name;
135       raw_string_ostream(Name)
136           << "std::pair<" << SerializationTypeNameSequence<T1, T2>() << ">";
137       return Name;
138     }();
139     return Name.data();
140   }
141 };
142 
143 template <typename... ArgTs> class SerializationTypeName<std::tuple<ArgTs...>> {
144 public:
getName()145   static const char *getName() {
146     static std::string Name = [] {
147       std::string Name;
148       raw_string_ostream(Name)
149           << "std::tuple<" << SerializationTypeNameSequence<ArgTs...>() << ">";
150       return Name;
151     }();
152     return Name.data();
153   }
154 };
155 
156 template <typename T> class SerializationTypeName<Optional<T>> {
157 public:
getName()158   static const char *getName() {
159     static std::string Name = [] {
160       std::string Name;
161       raw_string_ostream(Name)
162           << "Optional<" << SerializationTypeName<T>::getName() << ">";
163       return Name;
164     }();
165     return Name.data();
166   }
167 };
168 
169 template <typename T> class SerializationTypeName<std::vector<T>> {
170 public:
getName()171   static const char *getName() {
172     static std::string Name = [] {
173       std::string Name;
174       raw_string_ostream(Name)
175           << "std::vector<" << SerializationTypeName<T>::getName() << ">";
176       return Name;
177     }();
178     return Name.data();
179   }
180 };
181 
182 template <typename T> class SerializationTypeName<std::set<T>> {
183 public:
getName()184   static const char *getName() {
185     static std::string Name = [] {
186       std::string Name;
187       raw_string_ostream(Name)
188           << "std::set<" << SerializationTypeName<T>::getName() << ">";
189       return Name;
190     }();
191     return Name.data();
192   }
193 };
194 
195 template <typename K, typename V> class SerializationTypeName<std::map<K, V>> {
196 public:
getName()197   static const char *getName() {
198     static std::string Name = [] {
199       std::string Name;
200       raw_string_ostream(Name)
201           << "std::map<" << SerializationTypeNameSequence<K, V>() << ">";
202       return Name;
203     }();
204     return Name.data();
205   }
206 };
207 
208 /// The SerializationTraits<ChannelT, T> class describes how to serialize and
209 /// deserialize an instance of type T to/from an abstract channel of type
210 /// ChannelT. It also provides a representation of the type's name via the
211 /// getName method.
212 ///
213 /// Specializations of this class should provide the following functions:
214 ///
215 ///   @code{.cpp}
216 ///
217 ///   static const char* getName();
218 ///   static Error serialize(ChannelT&, const T&);
219 ///   static Error deserialize(ChannelT&, T&);
220 ///
221 ///   @endcode
222 ///
223 /// The third argument of SerializationTraits is intended to support SFINAE.
224 /// E.g.:
225 ///
226 ///   @code{.cpp}
227 ///
228 ///   class MyVirtualChannel { ... };
229 ///
230 ///   template <DerivedChannelT>
231 ///   class SerializationTraits<DerivedChannelT, bool,
232 ///         std::enable_if_t<
233 ///           std::is_base_of<VirtChannel, DerivedChannel>::value
234 ///         >> {
235 ///   public:
236 ///     static const char* getName() { ... };
237 ///   }
238 ///
239 ///   @endcode
240 template <typename ChannelT, typename WireType,
241           typename ConcreteType = WireType, typename = void>
242 class SerializationTraits;
243 
244 template <typename ChannelT> class SequenceTraits {
245 public:
emitSeparator(ChannelT & C)246   static Error emitSeparator(ChannelT &C) { return Error::success(); }
consumeSeparator(ChannelT & C)247   static Error consumeSeparator(ChannelT &C) { return Error::success(); }
248 };
249 
250 /// Utility class for serializing sequences of values of varying types.
251 /// Specializations of this class contain 'serialize' and 'deserialize' methods
252 /// for the given channel. The ArgTs... list will determine the "over-the-wire"
253 /// types to be serialized. The serialize and deserialize methods take a list
254 /// CArgTs... ("caller arg types") which must be the same length as ArgTs...,
255 /// but may be different types from ArgTs, provided that for each CArgT there
256 /// is a SerializationTraits specialization
257 /// SerializeTraits<ChannelT, ArgT, CArgT> with methods that can serialize the
258 /// caller argument to over-the-wire value.
259 template <typename ChannelT, typename... ArgTs> class SequenceSerialization;
260 
261 template <typename ChannelT> class SequenceSerialization<ChannelT> {
262 public:
serialize(ChannelT & C)263   static Error serialize(ChannelT &C) { return Error::success(); }
deserialize(ChannelT & C)264   static Error deserialize(ChannelT &C) { return Error::success(); }
265 };
266 
267 template <typename ChannelT, typename ArgT>
268 class SequenceSerialization<ChannelT, ArgT> {
269 public:
serialize(ChannelT & C,CArgT && CArg)270   template <typename CArgT> static Error serialize(ChannelT &C, CArgT &&CArg) {
271     return SerializationTraits<ChannelT, ArgT, std::decay_t<CArgT>>::serialize(
272         C, std::forward<CArgT>(CArg));
273   }
274 
deserialize(ChannelT & C,CArgT & CArg)275   template <typename CArgT> static Error deserialize(ChannelT &C, CArgT &CArg) {
276     return SerializationTraits<ChannelT, ArgT, CArgT>::deserialize(C, CArg);
277   }
278 };
279 
280 template <typename ChannelT, typename ArgT, typename... ArgTs>
281 class SequenceSerialization<ChannelT, ArgT, ArgTs...> {
282 public:
283   template <typename CArgT, typename... CArgTs>
serialize(ChannelT & C,CArgT && CArg,CArgTs &&...CArgs)284   static Error serialize(ChannelT &C, CArgT &&CArg, CArgTs &&...CArgs) {
285     if (auto Err =
286             SerializationTraits<ChannelT, ArgT, std::decay_t<CArgT>>::serialize(
287                 C, std::forward<CArgT>(CArg)))
288       return Err;
289     if (auto Err = SequenceTraits<ChannelT>::emitSeparator(C))
290       return Err;
291     return SequenceSerialization<ChannelT, ArgTs...>::serialize(
292         C, std::forward<CArgTs>(CArgs)...);
293   }
294 
295   template <typename CArgT, typename... CArgTs>
deserialize(ChannelT & C,CArgT & CArg,CArgTs &...CArgs)296   static Error deserialize(ChannelT &C, CArgT &CArg, CArgTs &...CArgs) {
297     if (auto Err =
298             SerializationTraits<ChannelT, ArgT, CArgT>::deserialize(C, CArg))
299       return Err;
300     if (auto Err = SequenceTraits<ChannelT>::consumeSeparator(C))
301       return Err;
302     return SequenceSerialization<ChannelT, ArgTs...>::deserialize(C, CArgs...);
303   }
304 };
305 
306 template <typename ChannelT, typename... ArgTs>
serializeSeq(ChannelT & C,ArgTs &&...Args)307 Error serializeSeq(ChannelT &C, ArgTs &&...Args) {
308   return SequenceSerialization<ChannelT, std::decay_t<ArgTs>...>::serialize(
309       C, std::forward<ArgTs>(Args)...);
310 }
311 
312 template <typename ChannelT, typename... ArgTs>
deserializeSeq(ChannelT & C,ArgTs &...Args)313 Error deserializeSeq(ChannelT &C, ArgTs &...Args) {
314   return SequenceSerialization<ChannelT, ArgTs...>::deserialize(C, Args...);
315 }
316 
317 template <typename ChannelT> class SerializationTraits<ChannelT, Error> {
318 public:
319   using WrappedErrorSerializer =
320       std::function<Error(ChannelT &C, const ErrorInfoBase &)>;
321 
322   using WrappedErrorDeserializer =
323       std::function<Error(ChannelT &C, Error &Err)>;
324 
325   template <typename ErrorInfoT, typename SerializeFtor,
326             typename DeserializeFtor>
registerErrorType(std::string Name,SerializeFtor Serialize,DeserializeFtor Deserialize)327   static void registerErrorType(std::string Name, SerializeFtor Serialize,
328                                 DeserializeFtor Deserialize) {
329     assert(!Name.empty() &&
330            "The empty string is reserved for the Success value");
331 
332     const std::string *KeyName = nullptr;
333     {
334       // We're abusing the stability of std::map here: We take a reference to
335       // the key of the deserializers map to save us from duplicating the string
336       // in the serializer. This should be changed to use a stringpool if we
337       // switch to a map type that may move keys in memory.
338       std::lock_guard<std::recursive_mutex> Lock(DeserializersMutex);
339       auto I = Deserializers.insert(
340           Deserializers.begin(),
341           std::make_pair(std::move(Name), std::move(Deserialize)));
342       KeyName = &I->first;
343     }
344 
345     {
346       assert(KeyName != nullptr && "No keyname pointer");
347       std::lock_guard<std::recursive_mutex> Lock(SerializersMutex);
348       Serializers[ErrorInfoT::classID()] =
349           [KeyName, Serialize = std::move(Serialize)](
350               ChannelT &C, const ErrorInfoBase &EIB) -> Error {
351         assert(EIB.dynamicClassID() == ErrorInfoT::classID() &&
352                "Serializer called for wrong error type");
353         if (auto Err = serializeSeq(C, *KeyName))
354           return Err;
355         return Serialize(C, static_cast<const ErrorInfoT &>(EIB));
356       };
357     }
358   }
359 
serialize(ChannelT & C,Error && Err)360   static Error serialize(ChannelT &C, Error &&Err) {
361     std::lock_guard<std::recursive_mutex> Lock(SerializersMutex);
362 
363     if (!Err)
364       return serializeSeq(C, std::string());
365 
366     return handleErrors(std::move(Err), [&C](const ErrorInfoBase &EIB) {
367       auto SI = Serializers.find(EIB.dynamicClassID());
368       if (SI == Serializers.end())
369         return serializeAsStringError(C, EIB);
370       return (SI->second)(C, EIB);
371     });
372   }
373 
deserialize(ChannelT & C,Error & Err)374   static Error deserialize(ChannelT &C, Error &Err) {
375     std::lock_guard<std::recursive_mutex> Lock(DeserializersMutex);
376 
377     std::string Key;
378     if (auto Err = deserializeSeq(C, Key))
379       return Err;
380 
381     if (Key.empty()) {
382       ErrorAsOutParameter EAO(&Err);
383       Err = Error::success();
384       return Error::success();
385     }
386 
387     auto DI = Deserializers.find(Key);
388     assert(DI != Deserializers.end() && "No deserializer for error type");
389     return (DI->second)(C, Err);
390   }
391 
392 private:
serializeAsStringError(ChannelT & C,const ErrorInfoBase & EIB)393   static Error serializeAsStringError(ChannelT &C, const ErrorInfoBase &EIB) {
394     std::string ErrMsg;
395     {
396       raw_string_ostream ErrMsgStream(ErrMsg);
397       EIB.log(ErrMsgStream);
398     }
399     return serialize(C, make_error<StringError>(std::move(ErrMsg),
400                                                 inconvertibleErrorCode()));
401   }
402 
403   static std::recursive_mutex SerializersMutex;
404   static std::recursive_mutex DeserializersMutex;
405   static std::map<const void *, WrappedErrorSerializer> Serializers;
406   static std::map<std::string, WrappedErrorDeserializer> Deserializers;
407 };
408 
409 template <typename ChannelT>
410 std::recursive_mutex SerializationTraits<ChannelT, Error>::SerializersMutex;
411 
412 template <typename ChannelT>
413 std::recursive_mutex SerializationTraits<ChannelT, Error>::DeserializersMutex;
414 
415 template <typename ChannelT>
416 std::map<const void *,
417          typename SerializationTraits<ChannelT, Error>::WrappedErrorSerializer>
418     SerializationTraits<ChannelT, Error>::Serializers;
419 
420 template <typename ChannelT>
421 std::map<std::string, typename SerializationTraits<
422                           ChannelT, Error>::WrappedErrorDeserializer>
423     SerializationTraits<ChannelT, Error>::Deserializers;
424 
425 /// Registers a serializer and deserializer for the given error type on the
426 /// given channel type.
427 template <typename ChannelT, typename ErrorInfoT, typename SerializeFtor,
428           typename DeserializeFtor>
registerErrorSerialization(std::string Name,SerializeFtor && Serialize,DeserializeFtor && Deserialize)429 void registerErrorSerialization(std::string Name, SerializeFtor &&Serialize,
430                                 DeserializeFtor &&Deserialize) {
431   SerializationTraits<ChannelT, Error>::template registerErrorType<ErrorInfoT>(
432       std::move(Name), std::forward<SerializeFtor>(Serialize),
433       std::forward<DeserializeFtor>(Deserialize));
434 }
435 
436 /// Registers serialization/deserialization for StringError.
registerStringError()437 template <typename ChannelT> void registerStringError() {
438   static bool AlreadyRegistered = false;
439   if (!AlreadyRegistered) {
440     registerErrorSerialization<ChannelT, StringError>(
441         "StringError",
442         [](ChannelT &C, const StringError &SE) {
443           return serializeSeq(C, SE.getMessage());
444         },
445         [](ChannelT &C, Error &Err) -> Error {
446           ErrorAsOutParameter EAO(&Err);
447           std::string Msg;
448           if (auto E2 = deserializeSeq(C, Msg))
449             return E2;
450           Err = make_error<StringError>(
451               std::move(Msg),
452               orcError(OrcErrorCode::UnknownErrorCodeFromRemote));
453           return Error::success();
454         });
455     AlreadyRegistered = true;
456   }
457 }
458 
459 /// SerializationTraits for Expected<T1> from an Expected<T2>.
460 template <typename ChannelT, typename T1, typename T2>
461 class SerializationTraits<ChannelT, Expected<T1>, Expected<T2>> {
462 public:
serialize(ChannelT & C,Expected<T2> && ValOrErr)463   static Error serialize(ChannelT &C, Expected<T2> &&ValOrErr) {
464     if (ValOrErr) {
465       if (auto Err = serializeSeq(C, true))
466         return Err;
467       return SerializationTraits<ChannelT, T1, T2>::serialize(C, *ValOrErr);
468     }
469     if (auto Err = serializeSeq(C, false))
470       return Err;
471     return serializeSeq(C, ValOrErr.takeError());
472   }
473 
deserialize(ChannelT & C,Expected<T2> & ValOrErr)474   static Error deserialize(ChannelT &C, Expected<T2> &ValOrErr) {
475     ExpectedAsOutParameter<T2> EAO(&ValOrErr);
476     bool HasValue;
477     if (auto Err = deserializeSeq(C, HasValue))
478       return Err;
479     if (HasValue)
480       return SerializationTraits<ChannelT, T1, T2>::deserialize(C, *ValOrErr);
481     Error Err = Error::success();
482     if (auto E2 = deserializeSeq(C, Err))
483       return E2;
484     ValOrErr = std::move(Err);
485     return Error::success();
486   }
487 };
488 
489 /// SerializationTraits for Expected<T1> from a T2.
490 template <typename ChannelT, typename T1, typename T2>
491 class SerializationTraits<ChannelT, Expected<T1>, T2> {
492 public:
serialize(ChannelT & C,T2 && Val)493   static Error serialize(ChannelT &C, T2 &&Val) {
494     return serializeSeq(C, Expected<T2>(std::forward<T2>(Val)));
495   }
496 };
497 
498 /// SerializationTraits for Expected<T1> from an Error.
499 template <typename ChannelT, typename T>
500 class SerializationTraits<ChannelT, Expected<T>, Error> {
501 public:
serialize(ChannelT & C,Error && Err)502   static Error serialize(ChannelT &C, Error &&Err) {
503     return serializeSeq(C, Expected<T>(std::move(Err)));
504   }
505 };
506 
507 /// SerializationTraits default specialization for std::pair.
508 template <typename ChannelT, typename T1, typename T2, typename T3, typename T4>
509 class SerializationTraits<ChannelT, std::pair<T1, T2>, std::pair<T3, T4>> {
510 public:
serialize(ChannelT & C,const std::pair<T3,T4> & V)511   static Error serialize(ChannelT &C, const std::pair<T3, T4> &V) {
512     if (auto Err = SerializationTraits<ChannelT, T1, T3>::serialize(C, V.first))
513       return Err;
514     return SerializationTraits<ChannelT, T2, T4>::serialize(C, V.second);
515   }
516 
deserialize(ChannelT & C,std::pair<T3,T4> & V)517   static Error deserialize(ChannelT &C, std::pair<T3, T4> &V) {
518     if (auto Err =
519             SerializationTraits<ChannelT, T1, T3>::deserialize(C, V.first))
520       return Err;
521     return SerializationTraits<ChannelT, T2, T4>::deserialize(C, V.second);
522   }
523 };
524 
525 /// SerializationTraits default specialization for std::tuple.
526 template <typename ChannelT, typename... ArgTs>
527 class SerializationTraits<ChannelT, std::tuple<ArgTs...>> {
528 public:
529   /// RPC channel serialization for std::tuple.
serialize(ChannelT & C,const std::tuple<ArgTs...> & V)530   static Error serialize(ChannelT &C, const std::tuple<ArgTs...> &V) {
531     return serializeTupleHelper(C, V, std::index_sequence_for<ArgTs...>());
532   }
533 
534   /// RPC channel deserialization for std::tuple.
deserialize(ChannelT & C,std::tuple<ArgTs...> & V)535   static Error deserialize(ChannelT &C, std::tuple<ArgTs...> &V) {
536     return deserializeTupleHelper(C, V, std::index_sequence_for<ArgTs...>());
537   }
538 
539 private:
540   // Serialization helper for std::tuple.
541   template <size_t... Is>
serializeTupleHelper(ChannelT & C,const std::tuple<ArgTs...> & V,std::index_sequence<Is...> _)542   static Error serializeTupleHelper(ChannelT &C, const std::tuple<ArgTs...> &V,
543                                     std::index_sequence<Is...> _) {
544     return serializeSeq(C, std::get<Is>(V)...);
545   }
546 
547   // Serialization helper for std::tuple.
548   template <size_t... Is>
deserializeTupleHelper(ChannelT & C,std::tuple<ArgTs...> & V,std::index_sequence<Is...> _)549   static Error deserializeTupleHelper(ChannelT &C, std::tuple<ArgTs...> &V,
550                                       std::index_sequence<Is...> _) {
551     return deserializeSeq(C, std::get<Is>(V)...);
552   }
553 };
554 
555 template <typename ChannelT, typename T>
556 class SerializationTraits<ChannelT, Optional<T>> {
557 public:
558   /// Serialize an Optional<T>.
serialize(ChannelT & C,const Optional<T> & O)559   static Error serialize(ChannelT &C, const Optional<T> &O) {
560     if (auto Err = serializeSeq(C, O != None))
561       return Err;
562     if (O)
563       if (auto Err = serializeSeq(C, *O))
564         return Err;
565     return Error::success();
566   }
567 
568   /// Deserialize an Optional<T>.
deserialize(ChannelT & C,Optional<T> & O)569   static Error deserialize(ChannelT &C, Optional<T> &O) {
570     bool HasValue = false;
571     if (auto Err = deserializeSeq(C, HasValue))
572       return Err;
573     if (HasValue)
574       if (auto Err = deserializeSeq(C, *O))
575         return Err;
576     return Error::success();
577   };
578 };
579 
580 /// SerializationTraits default specialization for std::vector.
581 template <typename ChannelT, typename T>
582 class SerializationTraits<ChannelT, std::vector<T>> {
583 public:
584   /// Serialize a std::vector<T> from std::vector<T>.
serialize(ChannelT & C,const std::vector<T> & V)585   static Error serialize(ChannelT &C, const std::vector<T> &V) {
586     if (auto Err = serializeSeq(C, static_cast<uint64_t>(V.size())))
587       return Err;
588 
589     for (const auto &E : V)
590       if (auto Err = serializeSeq(C, E))
591         return Err;
592 
593     return Error::success();
594   }
595 
596   /// Deserialize a std::vector<T> to a std::vector<T>.
deserialize(ChannelT & C,std::vector<T> & V)597   static Error deserialize(ChannelT &C, std::vector<T> &V) {
598     assert(V.empty() &&
599            "Expected default-constructed vector to deserialize into");
600 
601     uint64_t Count = 0;
602     if (auto Err = deserializeSeq(C, Count))
603       return Err;
604 
605     V.resize(Count);
606     for (auto &E : V)
607       if (auto Err = deserializeSeq(C, E))
608         return Err;
609 
610     return Error::success();
611   }
612 };
613 
614 /// Enable vector serialization from an ArrayRef.
615 template <typename ChannelT, typename T>
616 class SerializationTraits<ChannelT, std::vector<T>, ArrayRef<T>> {
617 public:
serialize(ChannelT & C,ArrayRef<T> V)618   static Error serialize(ChannelT &C, ArrayRef<T> V) {
619     if (auto Err = serializeSeq(C, static_cast<uint64_t>(V.size())))
620       return Err;
621 
622     for (const auto &E : V)
623       if (auto Err = serializeSeq(C, E))
624         return Err;
625 
626     return Error::success();
627   }
628 };
629 
630 template <typename ChannelT, typename T, typename T2>
631 class SerializationTraits<ChannelT, std::set<T>, std::set<T2>> {
632 public:
633   /// Serialize a std::set<T> from std::set<T2>.
serialize(ChannelT & C,const std::set<T2> & S)634   static Error serialize(ChannelT &C, const std::set<T2> &S) {
635     if (auto Err = serializeSeq(C, static_cast<uint64_t>(S.size())))
636       return Err;
637 
638     for (const auto &E : S)
639       if (auto Err = SerializationTraits<ChannelT, T, T2>::serialize(C, E))
640         return Err;
641 
642     return Error::success();
643   }
644 
645   /// Deserialize a std::set<T> to a std::set<T>.
deserialize(ChannelT & C,std::set<T2> & S)646   static Error deserialize(ChannelT &C, std::set<T2> &S) {
647     assert(S.empty() && "Expected default-constructed set to deserialize into");
648 
649     uint64_t Count = 0;
650     if (auto Err = deserializeSeq(C, Count))
651       return Err;
652 
653     while (Count-- != 0) {
654       T2 Val;
655       if (auto Err = SerializationTraits<ChannelT, T, T2>::deserialize(C, Val))
656         return Err;
657 
658       auto Added = S.insert(Val).second;
659       if (!Added)
660         return make_error<StringError>("Duplicate element in deserialized set",
661                                        orcError(OrcErrorCode::UnknownORCError));
662     }
663 
664     return Error::success();
665   }
666 };
667 
668 template <typename ChannelT, typename K, typename V, typename K2, typename V2>
669 class SerializationTraits<ChannelT, std::map<K, V>, std::map<K2, V2>> {
670 public:
671   /// Serialize a std::map<K, V> from std::map<K2, V2>.
serialize(ChannelT & C,const std::map<K2,V2> & M)672   static Error serialize(ChannelT &C, const std::map<K2, V2> &M) {
673     if (auto Err = serializeSeq(C, static_cast<uint64_t>(M.size())))
674       return Err;
675 
676     for (const auto &E : M) {
677       if (auto Err =
678               SerializationTraits<ChannelT, K, K2>::serialize(C, E.first))
679         return Err;
680       if (auto Err =
681               SerializationTraits<ChannelT, V, V2>::serialize(C, E.second))
682         return Err;
683     }
684 
685     return Error::success();
686   }
687 
688   /// Deserialize a std::map<K, V> to a std::map<K, V>.
deserialize(ChannelT & C,std::map<K2,V2> & M)689   static Error deserialize(ChannelT &C, std::map<K2, V2> &M) {
690     assert(M.empty() && "Expected default-constructed map to deserialize into");
691 
692     uint64_t Count = 0;
693     if (auto Err = deserializeSeq(C, Count))
694       return Err;
695 
696     while (Count-- != 0) {
697       std::pair<K2, V2> Val;
698       if (auto Err =
699               SerializationTraits<ChannelT, K, K2>::deserialize(C, Val.first))
700         return Err;
701 
702       if (auto Err =
703               SerializationTraits<ChannelT, V, V2>::deserialize(C, Val.second))
704         return Err;
705 
706       auto Added = M.insert(Val).second;
707       if (!Added)
708         return make_error<StringError>("Duplicate element in deserialized map",
709                                        orcError(OrcErrorCode::UnknownORCError));
710     }
711 
712     return Error::success();
713   }
714 };
715 
716 template <typename ChannelT, typename K, typename V, typename K2, typename V2>
717 class SerializationTraits<ChannelT, std::map<K, V>, DenseMap<K2, V2>> {
718 public:
719   /// Serialize a std::map<K, V> from DenseMap<K2, V2>.
serialize(ChannelT & C,const DenseMap<K2,V2> & M)720   static Error serialize(ChannelT &C, const DenseMap<K2, V2> &M) {
721     if (auto Err = serializeSeq(C, static_cast<uint64_t>(M.size())))
722       return Err;
723 
724     for (auto &E : M) {
725       if (auto Err =
726               SerializationTraits<ChannelT, K, K2>::serialize(C, E.first))
727         return Err;
728 
729       if (auto Err =
730               SerializationTraits<ChannelT, V, V2>::serialize(C, E.second))
731         return Err;
732     }
733 
734     return Error::success();
735   }
736 
737   /// Serialize a std::map<K, V> from DenseMap<K2, V2>.
deserialize(ChannelT & C,DenseMap<K2,V2> & M)738   static Error deserialize(ChannelT &C, DenseMap<K2, V2> &M) {
739     assert(M.empty() && "Expected default-constructed map to deserialize into");
740 
741     uint64_t Count = 0;
742     if (auto Err = deserializeSeq(C, Count))
743       return Err;
744 
745     while (Count-- != 0) {
746       std::pair<K2, V2> Val;
747       if (auto Err =
748               SerializationTraits<ChannelT, K, K2>::deserialize(C, Val.first))
749         return Err;
750 
751       if (auto Err =
752               SerializationTraits<ChannelT, V, V2>::deserialize(C, Val.second))
753         return Err;
754 
755       auto Added = M.insert(Val).second;
756       if (!Added)
757         return make_error<StringError>("Duplicate element in deserialized map",
758                                        orcError(OrcErrorCode::UnknownORCError));
759     }
760 
761     return Error::success();
762   }
763 };
764 
765 } // namespace shared
766 } // end namespace orc
767 } // end namespace llvm
768 
769 #endif // LLVM_EXECUTIONENGINE_ORC_SHARED_SERIALIZATION_H
770