#pragma once #include #include #include namespace DB { /** Функции - логические связки: and, or, not, xor. * Принимают любые числовые типы, возвращают UInt8, содержащий 0 или 1. */ template struct AndImpl { static inline bool isSaturable() { return true; } static inline bool isSaturatedValue(UInt8 a) { return !a; } static inline UInt8 apply(UInt8 a, B b) { return a && b; } }; template struct OrImpl { static inline bool isSaturable() { return true; } static inline bool isSaturatedValue(UInt8 a) { return a; } static inline UInt8 apply(UInt8 a, B b) { return a || b; } }; template struct XorImpl { static inline bool isSaturable() { return false; } static inline bool isSaturatedValue(UInt8 a) { return false; } static inline UInt8 apply(UInt8 a, B b) { return (!a) != (!b); } }; template struct NotImpl { typedef UInt8 ResultType; static inline UInt8 apply(A a) { return !a; } }; typedef ColumnVector::Container_t UInt8Container; typedef std::vector *> UInt8ColumnPtrs; template struct AssociativeOperationImpl { /// Выбрасывает N последних столбцов из in (если их меньше, то все) и кладет в result их комбинацию. static void execute(UInt8ColumnPtrs & in, UInt8Container & result) { if (N > in.size()) { AssociativeOperationImpl::execute(in, result); return; } AssociativeOperationImpl operation(in); in.erase(in.end() - N, in.end()); size_t n = result.size(); for (size_t i = 0; i < n; ++i) { result[i] = operation.apply(i); } } const UInt8Container & vec; AssociativeOperationImpl continuation; /// Запоминает последние N столбцов из in. AssociativeOperationImpl(UInt8ColumnPtrs & in) : vec(in[in.size() - N]->getData()), continuation(in) {} /// Возвращает комбинацию значений в i-й строке всех столбцов, запомненных в конструкторе. inline UInt8 apply(size_t i) const { if (Op::isSaturable()) { UInt8 a = vec[i]; return Op::isSaturatedValue(a) ? a : continuation.apply(i); } else { return Op::apply(vec[i], continuation.apply(i)); } } }; template struct AssociativeOperationImpl { static void execute(UInt8ColumnPtrs & in, UInt8Container & result) { throw Exception("Logical error: AssociativeOperationImpl::execute called", ErrorCodes::LOGICAL_ERROR); } const UInt8Container & vec; AssociativeOperationImpl(UInt8ColumnPtrs & in) : vec(in[in.size() - 1]->getData()) {} inline UInt8 apply(size_t i) const { return vec[i]; } }; template