diff --git a/dbms/include/DB/Functions/FunctionsRound.h b/dbms/include/DB/Functions/FunctionsRound.h index 6731ba31d3f..497fefa79e9 100644 --- a/dbms/include/DB/Functions/FunctionsRound.h +++ b/dbms/include/DB/Functions/FunctionsRound.h @@ -103,7 +103,7 @@ namespace DB return val; else { - size_t power = PowersTable::values.at(precision); + size_t power = PowersTable::values[precision]; return Op::apply(val * power) / power; } } @@ -158,19 +158,71 @@ namespace DB } }; +namespace +{ + /// Следующий код генерирует во время сборки таблицу степеней числа 10. + + /// Отдельные степени числа 10. + + template + struct PowerOf10 + { + static const size_t value = 10 * PowerOf10::value; + }; + + template<> + struct PowerOf10<0> + { + static const size_t value = 1; + }; + + /// Объявление и определение контейнера содержащего таблицу степеней числа 10. + + template + struct TableContainer + { + static const std::array values; + }; + + template + const std::array TableContainer::values = { TArgs... }; + + /// Генератор первых N степеней. + + template + struct FillArrayImpl + { + using result = typename FillArrayImpl::value, TArgs...>::result; + }; + + template + struct FillArrayImpl<0, TArgs...> + { + using result = TableContainer::value, TArgs...>; + }; + + template + struct FillArray + { + using result = typename FillArrayImpl::result; + }; +} + /** Шаблон для функцией, которые вычисляют приближенное значение входного параметра * типа (U)Int8/16/32/64 или Float32/64 и принимают дополнительный необязятельный * параметр указывающий сколько знаков после запятой оставить (по умолчанию - 0). * Op - функция (round/floor/ceil) - * PowersTable - таблица степеней числа 10 */ - template class Op, typename PowersTable, typename Name> + template class Op, typename Name> class FunctionApproximating : public IFunction { public: static constexpr auto name = Name::name; static IFunction * create(const Context & context) { return new FunctionApproximating; } + private: + using PowersOf10 = FillArray::digits10 + 1>::result; + private: template bool checkType(const IDataType * type) const @@ -196,7 +248,7 @@ namespace DB const PODArray & a = col->getData(); size_t size = a.size(); for (size_t i = 0; i < size; ++i) - vec_res[i] = FunctionApproximatingImpl::apply(a[i], precision); + vec_res[i] = FunctionApproximatingImpl::apply(a[i], precision); return true; } @@ -206,7 +258,7 @@ namespace DB if (arguments.size() == 2) precision = getPrecision(block.getByPosition(arguments[1]).column); - T res = FunctionApproximatingImpl::apply(col->getData(), precision); + T res = FunctionApproximatingImpl::apply(col->getData(), precision); ColumnConst * col_res = new ColumnConst(col->size(), res); block.getByPosition(result).column = col_res; @@ -387,57 +439,6 @@ namespace return floor(val); } }; - - /// Следующий код генерирует во время сборки таблицу степеней числа 10. - - /// Отдельные степени числа 10. - - template - struct PowerOf10 - { - static const size_t value = 10 * PowerOf10::value; - }; - - template<> - struct PowerOf10<0> - { - static const size_t value = 1; - }; - - /// Объявление и определение контейнера содержащего таблицу степеней числа 10. - - template - struct TableContainer - { - static const std::array values; - }; - - template - const std::array TableContainer::values = { TArgs... }; - - /// Генератор первых N степеней. - - template - struct FillArrayImpl - { - using result = typename FillArrayImpl::value, TArgs...>::result; - }; - - template - struct FillArrayImpl<0, TArgs...> - { - using result = TableContainer::value, TArgs...>; - }; - - template - struct FillArray - { - using result = typename FillArrayImpl::result; - }; - - /// Сгенерить таблицу. - - using PowersOf10 = FillArray::digits10 + 1>::result; } struct NameRoundToExp2 { static constexpr auto name = "roundToExp2"; }; @@ -450,7 +451,7 @@ namespace typedef FunctionUnaryArithmetic FunctionRoundToExp2; typedef FunctionUnaryArithmetic FunctionRoundDuration; typedef FunctionUnaryArithmetic FunctionRoundAge; - typedef FunctionApproximating FunctionRound; - typedef FunctionApproximating FunctionCeil; - typedef FunctionApproximating FunctionFloor; + typedef FunctionApproximating FunctionRound; + typedef FunctionApproximating FunctionCeil; + typedef FunctionApproximating FunctionFloor; }