From af55445da3b5d021116c08eed91c0af0fd386f94 Mon Sep 17 00:00:00 2001 From: Andrey Mironov Date: Fri, 28 Nov 2014 19:09:29 +0300 Subject: [PATCH] dbms: implement abs(). [#METR-13613] --- .../DB/Functions/FunctionsArithmetic.h | 27 +++++++++++++++++++ dbms/include/DB/Functions/NumberTraits.h | 8 ++++++ dbms/src/Functions/FunctionsArithmetic.cpp | 1 + 3 files changed, 36 insertions(+) diff --git a/dbms/include/DB/Functions/FunctionsArithmetic.h b/dbms/include/DB/Functions/FunctionsArithmetic.h index 9fd2d7856dc..b00b31a1158 100644 --- a/dbms/include/DB/Functions/FunctionsArithmetic.h +++ b/dbms/include/DB/Functions/FunctionsArithmetic.h @@ -284,6 +284,31 @@ struct BitNotImpl } }; +template +struct AbsImpl +{ + typedef typename NumberTraits::ResultOfAbs::Type ResultType; + + template + static inline ResultType apply(T a, + typename std::enable_if::value && std::is_signed::value, void>::type * = nullptr) + { + return a < 0 ? static_cast(~a) + 1 : a; + } + + template + static inline ResultType apply(T a, + typename std::enable_if::value && std::is_unsigned::value, void>::type * = nullptr) + { + return static_cast(a); + } + + template + static inline ResultType apply(T a, typename std::enable_if::value, void>::type * = nullptr) + { + return static_cast(std::abs(a)); + } +}; /// this one is just for convenience template using If = typename std::conditional::type; @@ -783,6 +808,7 @@ struct NameDivideIntegral { static constexpr auto name = "intDiv"; }; struct NameDivideIntegralOrZero { static constexpr auto name = "intDivOrZero"; }; struct NameModulo { static constexpr auto name = "modulo"; }; struct NameNegate { static constexpr auto name = "negate"; }; +struct NameAbs { static constexpr auto name = "abs"; }; struct NameBitAnd { static constexpr auto name = "bitAnd"; }; struct NameBitOr { static constexpr auto name = "bitOr"; }; struct NameBitXor { static constexpr auto name = "bitXor"; }; @@ -798,6 +824,7 @@ typedef FunctionBinaryArithmetic Funct typedef FunctionBinaryArithmetic FunctionDivideIntegralOrZero; typedef FunctionBinaryArithmetic FunctionModulo; typedef FunctionUnaryArithmetic FunctionNegate; +typedef FunctionUnaryArithmetic FunctionAbs; typedef FunctionBinaryArithmetic FunctionBitAnd; typedef FunctionBinaryArithmetic FunctionBitOr; typedef FunctionBinaryArithmetic FunctionBitXor; diff --git a/dbms/include/DB/Functions/NumberTraits.h b/dbms/include/DB/Functions/NumberTraits.h index 89b2d834d54..2927fbd550b 100644 --- a/dbms/include/DB/Functions/NumberTraits.h +++ b/dbms/include/DB/Functions/NumberTraits.h @@ -154,6 +154,14 @@ namespace NumberTraits typename Next::Bits>::Type>::type>::Type Type; }; + template struct ResultOfAbs + { + typedef typename Construct< + Unsigned, + typename Traits::Floatness, + typename Traits ::Bits>::Type Type; + }; + /** При побитовых операциях получается целое число, битность которого равна максимальной из битностей аргументов. */ template struct ResultOfBit diff --git a/dbms/src/Functions/FunctionsArithmetic.cpp b/dbms/src/Functions/FunctionsArithmetic.cpp index dab8dc242eb..beb0851c5c1 100644 --- a/dbms/src/Functions/FunctionsArithmetic.cpp +++ b/dbms/src/Functions/FunctionsArithmetic.cpp @@ -14,6 +14,7 @@ void registerFunctionsArithmetic(FunctionFactory & factory) factory.registerFunction(); factory.registerFunction(); factory.registerFunction(); + factory.registerFunction(); factory.registerFunction(); factory.registerFunction(); factory.registerFunction();