| 1 | #pragma once | 
|---|
| 2 |  | 
|---|
| 3 | #include "Algorithms.h" | 
|---|
| 4 | #include "ArraySourceVisitor.h" | 
|---|
| 5 | #include "ArraySinkVisitor.h" | 
|---|
| 6 | #include "ValueSourceVisitor.h" | 
|---|
| 7 |  | 
|---|
| 8 |  | 
|---|
| 9 | namespace DB::GatherUtils | 
|---|
| 10 | { | 
|---|
| 11 | /// Base classes which selects template function implementation with concrete ArraySource or ArraySink | 
|---|
| 12 | /// Derived classes should implement selectImpl for ArraySourceSelector and ArraySinkSelector, | 
|---|
| 13 | ///  selectSourceSink for ArraySinkSourceSelector and selectSourcePair for ArraySourcePairSelector | 
|---|
| 14 |  | 
|---|
| 15 | template <typename Base, typename Tuple, int index, typename ... Args> | 
|---|
| 16 | void callSelectMemberFunctionWithTupleArgument(Tuple & tuple, Args && ... args) | 
|---|
| 17 | { | 
|---|
| 18 | if constexpr (index == std::tuple_size<Tuple>::value) | 
|---|
| 19 | Base::selectImpl(args ...); | 
|---|
| 20 | else | 
|---|
| 21 | callSelectMemberFunctionWithTupleArgument<Base, Tuple, index + 1>(tuple, args ..., std::get<index>(tuple)); | 
|---|
| 22 | } | 
|---|
| 23 |  | 
|---|
| 24 | template <typename Base, typename ... Args> | 
|---|
| 25 | struct ArraySourceSelectorVisitor : public ArraySourceVisitorImpl<ArraySourceSelectorVisitor<Base, Args ...>> | 
|---|
| 26 | { | 
|---|
| 27 | explicit ArraySourceSelectorVisitor(Args && ... args) : packed_args(args ...) {} | 
|---|
| 28 |  | 
|---|
| 29 | using Tuple = std::tuple<Args && ...>; | 
|---|
| 30 |  | 
|---|
| 31 | template <typename Source> | 
|---|
| 32 | void visitImpl(Source & source) | 
|---|
| 33 | { | 
|---|
| 34 | callSelectMemberFunctionWithTupleArgument<Base, Tuple, 0>(packed_args, source); | 
|---|
| 35 | } | 
|---|
| 36 |  | 
|---|
| 37 | Tuple packed_args; | 
|---|
| 38 | }; | 
|---|
| 39 |  | 
|---|
| 40 | template <typename Base> | 
|---|
| 41 | struct ArraySourceSelector | 
|---|
| 42 | { | 
|---|
| 43 | template <typename ... Args> | 
|---|
| 44 | static void select(IArraySource & source, Args && ... args) | 
|---|
| 45 | { | 
|---|
| 46 | ArraySourceSelectorVisitor<Base, Args ...> visitor(args ...); | 
|---|
| 47 | source.accept(visitor); | 
|---|
| 48 | } | 
|---|
| 49 | }; | 
|---|
| 50 |  | 
|---|
| 51 |  | 
|---|
| 52 | template <typename Base, typename ... Args> | 
|---|
| 53 | struct ArraySinkSelectorVisitor : public ArraySinkVisitorImpl<ArraySinkSelectorVisitor<Base, Args ...>> | 
|---|
| 54 | { | 
|---|
| 55 | explicit ArraySinkSelectorVisitor(Args && ... args) : packed_args(args ...) {} | 
|---|
| 56 |  | 
|---|
| 57 | using Tuple = std::tuple<Args && ...>; | 
|---|
| 58 |  | 
|---|
| 59 | template <typename Sink> | 
|---|
| 60 | void visitImpl(Sink & sink) | 
|---|
| 61 | { | 
|---|
| 62 | callSelectMemberFunctionWithTupleArgument<Base, Tuple, 0>(packed_args, sink); | 
|---|
| 63 | } | 
|---|
| 64 |  | 
|---|
| 65 | Tuple packed_args; | 
|---|
| 66 | }; | 
|---|
| 67 |  | 
|---|
| 68 | template <typename Base> | 
|---|
| 69 | struct ArraySinkSelector | 
|---|
| 70 | { | 
|---|
| 71 | template <typename ... Args> | 
|---|
| 72 | static void select(IArraySink & sink, Args && ... args) | 
|---|
| 73 | { | 
|---|
| 74 | ArraySinkSelectorVisitor<Base, Args ...> visitor(args ...); | 
|---|
| 75 | sink.accept(visitor); | 
|---|
| 76 | } | 
|---|
| 77 | }; | 
|---|
| 78 |  | 
|---|
| 79 |  | 
|---|
| 80 | template <typename Base, typename ... Args> | 
|---|
| 81 | struct ValueSourceSelectorVisitor : public ValueSourceVisitorImpl<ValueSourceSelectorVisitor<Base, Args ...>> | 
|---|
| 82 | { | 
|---|
| 83 | explicit ValueSourceSelectorVisitor(Args && ... args) : packed_args(args ...) {} | 
|---|
| 84 |  | 
|---|
| 85 | using Tuple = std::tuple<Args && ...>; | 
|---|
| 86 |  | 
|---|
| 87 | template <typename Source> | 
|---|
| 88 | void visitImpl(Source & source) | 
|---|
| 89 | { | 
|---|
| 90 | callSelectMemberFunctionWithTupleArgument<Base, Tuple, 0>(packed_args, source); | 
|---|
| 91 | } | 
|---|
| 92 |  | 
|---|
| 93 | Tuple packed_args; | 
|---|
| 94 | }; | 
|---|
| 95 |  | 
|---|
| 96 | template <typename Base> | 
|---|
| 97 | struct ValueSourceSelector | 
|---|
| 98 | { | 
|---|
| 99 | template <typename ... Args> | 
|---|
| 100 | static void select(IValueSource & source, Args && ... args) | 
|---|
| 101 | { | 
|---|
| 102 | ValueSourceSelectorVisitor<Base, Args ...> visitor(args ...); | 
|---|
| 103 | source.accept(visitor); | 
|---|
| 104 | } | 
|---|
| 105 | }; | 
|---|
| 106 |  | 
|---|
| 107 | template <typename Base> | 
|---|
| 108 | struct ArraySinkSourceSelector | 
|---|
| 109 | { | 
|---|
| 110 | template <typename ... Args> | 
|---|
| 111 | static void select(IArraySource & source, IArraySink & sink, Args && ... args) | 
|---|
| 112 | { | 
|---|
| 113 | ArraySinkSelector<Base>::select(sink, source, args ...); | 
|---|
| 114 | } | 
|---|
| 115 |  | 
|---|
| 116 | template <typename Sink, typename ... Args> | 
|---|
| 117 | static void selectImpl(Sink && sink, IArraySource & source, Args && ... args) | 
|---|
| 118 | { | 
|---|
| 119 | ArraySourceSelector<Base>::select(source, sink, args ...); | 
|---|
| 120 | } | 
|---|
| 121 |  | 
|---|
| 122 | template <typename Source, typename Sink, typename ... Args> | 
|---|
| 123 | static void selectImpl(Source && source, Sink && sink, Args && ... args) | 
|---|
| 124 | { | 
|---|
| 125 | Base::selectSourceSink(source, sink, args ...); | 
|---|
| 126 | } | 
|---|
| 127 | }; | 
|---|
| 128 |  | 
|---|
| 129 | template <typename Base> | 
|---|
| 130 | struct ArraySourcePairSelector | 
|---|
| 131 | { | 
|---|
| 132 | template <typename ... Args> | 
|---|
| 133 | static void select(IArraySource & first, IArraySource & second, Args && ... args) | 
|---|
| 134 | { | 
|---|
| 135 | ArraySourceSelector<Base>::select(first, second, args ...); | 
|---|
| 136 | } | 
|---|
| 137 |  | 
|---|
| 138 | template <typename FirstSource, typename ... Args> | 
|---|
| 139 | static void selectImpl(FirstSource && first, IArraySource & second, Args && ... args) | 
|---|
| 140 | { | 
|---|
| 141 | ArraySourceSelector<Base>::select(second, first, args ...); | 
|---|
| 142 | } | 
|---|
| 143 |  | 
|---|
| 144 | template <typename SecondSource, typename FirstSource, typename ... Args> | 
|---|
| 145 | static void selectImpl(SecondSource && second, FirstSource && first, Args && ... args) | 
|---|
| 146 | { | 
|---|
| 147 | Base::selectSourcePair(first, second, args ...); | 
|---|
| 148 | } | 
|---|
| 149 | }; | 
|---|
| 150 |  | 
|---|
| 151 | template <typename Base> | 
|---|
| 152 | struct ArrayAndValueSourceSelectorBySink : public ArraySinkSelector<ArrayAndValueSourceSelectorBySink<Base>> | 
|---|
| 153 | { | 
|---|
| 154 | template <typename Sink, typename ... Args> | 
|---|
| 155 | static void selectImpl(Sink && sink, IArraySource & array_source, IValueSource & value_source, Args && ... args) | 
|---|
| 156 | { | 
|---|
| 157 | using SynkType = typename std::decay<Sink>::type; | 
|---|
| 158 | using ArraySource = typename SynkType::CompatibleArraySource; | 
|---|
| 159 | using ValueSource = typename SynkType::CompatibleValueSource; | 
|---|
| 160 |  | 
|---|
| 161 | auto checkType = [] (auto source_ptr) | 
|---|
| 162 | { | 
|---|
| 163 | if (source_ptr == nullptr) | 
|---|
| 164 | throw Exception(demangle(typeid(Base).name()) + " expected " | 
|---|
| 165 | + demangle(typeid(typename SynkType::CompatibleArraySource).name()) | 
|---|
| 166 | + " or "+ demangle(typeid(ConstSource<typename SynkType::CompatibleArraySource>).name()) | 
|---|
| 167 | + " or "+ demangle(typeid(typename SynkType::CompatibleValueSource).name()) + | 
|---|
| 168 | + " or "+ demangle(typeid(ConstSource<typename SynkType::CompatibleValueSource>).name()) | 
|---|
| 169 | + " but got "+ demangle(typeid(*source_ptr).name()), ErrorCodes::LOGICAL_ERROR); | 
|---|
| 170 | }; | 
|---|
| 171 | auto checkTypeAndCallConcat = [& sink, & checkType, & args ...] (auto array_source_ptr, auto value_source_ptr) | 
|---|
| 172 | { | 
|---|
| 173 | checkType(array_source_ptr); | 
|---|
| 174 | checkType(value_source_ptr); | 
|---|
| 175 |  | 
|---|
| 176 | Base::selectArrayAndValueSourceBySink(*array_source_ptr, *value_source_ptr, sink, args ...); | 
|---|
| 177 | }; | 
|---|
| 178 |  | 
|---|
| 179 | if (array_source.isConst() && value_source.isConst()) | 
|---|
| 180 | checkTypeAndCallConcat(typeid_cast<ConstSource<ArraySource> *>(&array_source), | 
|---|
| 181 | typeid_cast<ConstSource<ValueSource> *>(&value_source)); | 
|---|
| 182 | else if (array_source.isConst()) | 
|---|
| 183 | checkTypeAndCallConcat(typeid_cast<ConstSource<ArraySource> *>(&array_source), | 
|---|
| 184 | typeid_cast<ValueSource *>(&value_source)); | 
|---|
| 185 | else if (value_source.isConst()) | 
|---|
| 186 | checkTypeAndCallConcat(typeid_cast<ArraySource *>(&array_source), | 
|---|
| 187 | typeid_cast<ConstSource<ValueSource> *>(&value_source)); | 
|---|
| 188 | else | 
|---|
| 189 | checkTypeAndCallConcat(typeid_cast<ArraySource *>(&array_source), | 
|---|
| 190 | typeid_cast<ValueSource *>(&value_source)); | 
|---|
| 191 | } | 
|---|
| 192 | }; | 
|---|
| 193 |  | 
|---|
| 194 | } | 
|---|
| 195 |  | 
|---|