proto_variant.h 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. #pragma once
  2. #include <yql/essentials/public/purecalc/common/interface.h>
  3. #include <array>
  4. namespace NYql::NPureCalc::NPrivate {
  5. using TProtoRawMultiOutput = std::pair<ui32, google::protobuf::Message*>;
  6. template <typename... T>
  7. using TProtoMultiOutput = std::variant<T*...>;
  8. template <size_t I, typename... T>
  9. using TProtoOutput = std::add_pointer_t<typename TTypeList<T...>::template TGet<I>>;
  10. template <size_t I, typename... T>
  11. TProtoMultiOutput<T...> InitProtobufsVariant(google::protobuf::Message* ptr) {
  12. static_assert(std::conjunction_v<std::is_base_of<google::protobuf::Message, T>...>);
  13. return TProtoMultiOutput<T...>(std::in_place_index<I>, static_cast<TProtoOutput<I, T...>>(ptr));
  14. }
  15. template <typename... T>
  16. class TProtobufsMappingBase {
  17. public:
  18. TProtobufsMappingBase()
  19. : InitFuncs_(BuildInitFuncs(std::make_index_sequence<sizeof...(T)>()))
  20. {
  21. }
  22. private:
  23. typedef TProtoMultiOutput<T...> (*initfunc)(google::protobuf::Message*);
  24. template <size_t... I>
  25. inline std::array<initfunc, sizeof...(T)> BuildInitFuncs(std::index_sequence<I...>) {
  26. return {&InitProtobufsVariant<I, T...>...};
  27. }
  28. protected:
  29. const std::array<initfunc, sizeof...(T)> InitFuncs_;
  30. };
  31. template <typename... T>
  32. class TProtobufsMappingStream: public IStream<TProtoMultiOutput<T...>>, public TProtobufsMappingBase<T...> {
  33. public:
  34. TProtobufsMappingStream(THolder<IStream<TProtoRawMultiOutput>> oldStream)
  35. : OldStream_(std::move(oldStream))
  36. {
  37. }
  38. public:
  39. TProtoMultiOutput<T...> Fetch() override {
  40. auto&& oldItem = OldStream_->Fetch();
  41. return this->InitFuncs_[oldItem.first](oldItem.second);
  42. }
  43. private:
  44. THolder<IStream<TProtoRawMultiOutput>> OldStream_;
  45. };
  46. template <typename... T>
  47. class TProtobufsMappingConsumer: public IConsumer<TProtoRawMultiOutput>, public TProtobufsMappingBase<T...> {
  48. public:
  49. TProtobufsMappingConsumer(THolder<IConsumer<TProtoMultiOutput<T...>>> oldConsumer)
  50. : OldConsumer_(std::move(oldConsumer))
  51. {
  52. }
  53. public:
  54. void OnObject(TProtoRawMultiOutput oldItem) override {
  55. OldConsumer_->OnObject(this->InitFuncs_[oldItem.first](oldItem.second));
  56. }
  57. void OnFinish() override {
  58. OldConsumer_->OnFinish();
  59. }
  60. private:
  61. THolder<IConsumer<TProtoMultiOutput<T...>>> OldConsumer_;
  62. };
  63. }