#pragma once #include #include #include #include #include namespace DB { /** Арифметические функции: +, -, *, /, %, * div (целочисленное деление), унарный минус. */ template struct PlusImpl { 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] = 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] = 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] = a + b[i]; } static void constant_constant(A a, B b, ResultType & c) { c = 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] = 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] = 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] = a * b[i]; } static void constant_constant(A a, B b, ResultType & c) { c = 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] = 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] = 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] = a - b[i]; } static void constant_constant(A a, B b, ResultType & c) { c = 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] = 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] = 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] = a / b[i]; } static void constant_constant(A a, B b, ResultType & c) { c = 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