#pragma once #include #include #include #include #include namespace DB { /** Арифметические функции: +, -, *, /, %, * intDiv (целочисленное деление), унарный минус. */ template struct PlusImpl { typedef typename NumberTraits::ResultOfAdditionMultiplication::Type ResultType; static void vector_vector(const std::vector & a, const std::vector & b, std::vector & c) { /// Далее везде, static_cast - чтобы не было неправильного результата в выражениях вида Int64 c = UInt32(a) * Int32(-1). size_t size = a.size(); for (size_t i = 0; i < size; ++i) c[i] = static_cast(a[i]) + b[i]; } static void vector_constant(const std::vector & a, B b, std::vector & c) { size_t size = a.size(); for (size_t i = 0; i < size; ++i) c[i] = static_cast(a[i]) + b; } static void constant_vector(A a, const std::vector & b, std::vector & c) { size_t size = b.size(); for (size_t i = 0; i < size; ++i) c[i] = static_cast(a) + b[i]; } static void constant_constant(A a, B b, ResultType & c) { c = static_cast(a) + b; } }; template struct MultiplyImpl { typedef typename NumberTraits::ResultOfAdditionMultiplication::Type ResultType; static void vector_vector(const std::vector & a, const std::vector & b, std::vector & c) { size_t size = a.size(); for (size_t i = 0; i < size; ++i) c[i] = static_cast(a[i]) * b[i]; } static void vector_constant(const std::vector & a, B b, std::vector & c) { size_t size = a.size(); for (size_t i = 0; i < size; ++i) c[i] = static_cast(a[i]) * b; } static void constant_vector(A a, const std::vector & b, std::vector & c) { size_t size = b.size(); for (size_t i = 0; i < size; ++i) c[i] = static_cast(a) * b[i]; } static void constant_constant(A a, B b, ResultType & c) { c = static_cast(a) * b; } }; template struct MinusImpl { typedef typename NumberTraits::ResultOfSubtraction::Type ResultType; static void vector_vector(const std::vector & a, const std::vector & b, std::vector & c) { size_t size = a.size(); for (size_t i = 0; i < size; ++i) c[i] = static_cast(a[i]) - b[i]; } static void vector_constant(const std::vector & a, B b, std::vector & c) { size_t size = a.size(); for (size_t i = 0; i < size; ++i) c[i] = static_cast(a[i]) - b; } static void constant_vector(A a, const std::vector & b, std::vector & c) { size_t size = b.size(); for (size_t i = 0; i < size; ++i) c[i] = static_cast(a) - b[i]; } static void constant_constant(A a, B b, ResultType & c) { c = static_cast(a) - b; } }; template struct DivideFloatingImpl { typedef typename NumberTraits::ResultOfFloatingPointDivision::Type ResultType; static void vector_vector(const std::vector & a, const std::vector & b, std::vector & c) { size_t size = a.size(); for (size_t i = 0; i < size; ++i) c[i] = static_cast(a[i]) / b[i]; } static void vector_constant(const std::vector & a, B b, std::vector & c) { size_t size = a.size(); for (size_t i = 0; i < size; ++i) c[i] = static_cast(a[i]) / b; } static void constant_vector(A a, const std::vector & b, std::vector & c) { size_t size = b.size(); for (size_t i = 0; i < size; ++i) c[i] = static_cast(a) / b[i]; } static void constant_constant(A a, B b, ResultType & c) { c = static_cast(a) / b; } }; template struct DivideIntegralImpl { typedef typename NumberTraits::ResultOfIntegerDivision::Type ResultType; static void vector_vector(const std::vector & a, const std::vector & b, std::vector & c) { size_t size = a.size(); for (size_t i = 0; i < size; ++i) c[i] = static_cast(a[i]) / b[i]; } static void vector_constant(const std::vector & a, B b, std::vector & c) { size_t size = a.size(); for (size_t i = 0; i < size; ++i) c[i] = static_cast(a[i]) / b; } static void constant_vector(A a, const std::vector & b, std::vector & c) { size_t size = b.size(); for (size_t i = 0; i < size; ++i) c[i] = static_cast(a) / b[i]; } static void constant_constant(A a, B b, ResultType & c) { c = static_cast(a) / b; } }; template struct ModuloImpl { typedef typename NumberTraits::ResultOfModulo::Type ResultType; static void vector_vector(const std::vector & a, const std::vector & b, std::vector & c) { size_t size = a.size(); for (size_t i = 0; i < size; ++i) c[i] = typename NumberTraits::ToInteger::Type(a[i]) % typename NumberTraits::ToInteger::Type(b[i]); } static void vector_constant(const std::vector & a, B b, std::vector & c) { size_t size = a.size(); for (size_t i = 0; i < size; ++i) c[i] = typename NumberTraits::ToInteger::Type(a[i]) % typename NumberTraits::ToInteger::Type(b); } static void constant_vector(A a, const std::vector & b, std::vector & c) { size_t size = b.size(); for (size_t i = 0; i < size; ++i) c[i] = typename NumberTraits::ToInteger::Type(a) % typename NumberTraits::ToInteger::Type(b[i]); } static void constant_constant(A a, B b, ResultType & c) { c = typename NumberTraits::ToInteger::Type(a) % typename NumberTraits::ToInteger::Type(b); } }; template struct NegateImpl { typedef typename NumberTraits::ResultOfNegate::Type ResultType; static void vector(const std::vector & a, std::vector & c) { size_t size = a.size(); for (size_t i = 0; i < size; ++i) c[i] = -a[i]; } static void constant(A a, ResultType & c) { c = -a; } }; template