dbms: implement abs(). [#METR-13613]

This commit is contained in:
Andrey Mironov 2014-11-28 19:09:29 +03:00
parent fae4eb388d
commit af55445da3
3 changed files with 36 additions and 0 deletions

View File

@ -284,6 +284,31 @@ struct BitNotImpl
} }
}; };
template<typename A>
struct AbsImpl
{
typedef typename NumberTraits::ResultOfAbs<A>::Type ResultType;
template<typename T = A>
static inline ResultType apply(T a,
typename std::enable_if<std::is_integral<T>::value && std::is_signed<T>::value, void>::type * = nullptr)
{
return a < 0 ? static_cast<ResultType>(~a) + 1 : a;
}
template<typename T = A>
static inline ResultType apply(T a,
typename std::enable_if<std::is_integral<T>::value && std::is_unsigned<T>::value, void>::type * = nullptr)
{
return static_cast<ResultType>(a);
}
template<typename T = A>
static inline ResultType apply(T a, typename std::enable_if<std::is_floating_point<T>::value, void>::type * = nullptr)
{
return static_cast<ResultType>(std::abs(a));
}
};
/// this one is just for convenience /// this one is just for convenience
template <bool B, typename T1, typename T2> using If = typename std::conditional<B, T1, T2>::type; template <bool B, typename T1, typename T2> using If = typename std::conditional<B, T1, T2>::type;
@ -783,6 +808,7 @@ struct NameDivideIntegral { static constexpr auto name = "intDiv"; };
struct NameDivideIntegralOrZero { static constexpr auto name = "intDivOrZero"; }; struct NameDivideIntegralOrZero { static constexpr auto name = "intDivOrZero"; };
struct NameModulo { static constexpr auto name = "modulo"; }; struct NameModulo { static constexpr auto name = "modulo"; };
struct NameNegate { static constexpr auto name = "negate"; }; struct NameNegate { static constexpr auto name = "negate"; };
struct NameAbs { static constexpr auto name = "abs"; };
struct NameBitAnd { static constexpr auto name = "bitAnd"; }; struct NameBitAnd { static constexpr auto name = "bitAnd"; };
struct NameBitOr { static constexpr auto name = "bitOr"; }; struct NameBitOr { static constexpr auto name = "bitOr"; };
struct NameBitXor { static constexpr auto name = "bitXor"; }; struct NameBitXor { static constexpr auto name = "bitXor"; };
@ -798,6 +824,7 @@ typedef FunctionBinaryArithmetic<DivideIntegralImpl, NameDivideIntegral> Funct
typedef FunctionBinaryArithmetic<DivideIntegralOrZeroImpl, NameDivideIntegralOrZero> FunctionDivideIntegralOrZero; typedef FunctionBinaryArithmetic<DivideIntegralOrZeroImpl, NameDivideIntegralOrZero> FunctionDivideIntegralOrZero;
typedef FunctionBinaryArithmetic<ModuloImpl, NameModulo> FunctionModulo; typedef FunctionBinaryArithmetic<ModuloImpl, NameModulo> FunctionModulo;
typedef FunctionUnaryArithmetic<NegateImpl, NameNegate> FunctionNegate; typedef FunctionUnaryArithmetic<NegateImpl, NameNegate> FunctionNegate;
typedef FunctionUnaryArithmetic<AbsImpl, NameAbs> FunctionAbs;
typedef FunctionBinaryArithmetic<BitAndImpl, NameBitAnd> FunctionBitAnd; typedef FunctionBinaryArithmetic<BitAndImpl, NameBitAnd> FunctionBitAnd;
typedef FunctionBinaryArithmetic<BitOrImpl, NameBitOr> FunctionBitOr; typedef FunctionBinaryArithmetic<BitOrImpl, NameBitOr> FunctionBitOr;
typedef FunctionBinaryArithmetic<BitXorImpl, NameBitXor> FunctionBitXor; typedef FunctionBinaryArithmetic<BitXorImpl, NameBitXor> FunctionBitXor;

View File

@ -154,6 +154,14 @@ namespace NumberTraits
typename Next<typename Traits<A>::Bits>::Type>::type>::Type Type; typename Next<typename Traits<A>::Bits>::Type>::type>::Type Type;
}; };
template <typename A> struct ResultOfAbs
{
typedef typename Construct<
Unsigned,
typename Traits<A>::Floatness,
typename Traits <A>::Bits>::Type Type;
};
/** При побитовых операциях получается целое число, битность которого равна максимальной из битностей аргументов. /** При побитовых операциях получается целое число, битность которого равна максимальной из битностей аргументов.
*/ */
template <typename A, typename B> struct ResultOfBit template <typename A, typename B> struct ResultOfBit

View File

@ -14,6 +14,7 @@ void registerFunctionsArithmetic(FunctionFactory & factory)
factory.registerFunction<FunctionDivideIntegralOrZero>(); factory.registerFunction<FunctionDivideIntegralOrZero>();
factory.registerFunction<FunctionModulo>(); factory.registerFunction<FunctionModulo>();
factory.registerFunction<FunctionNegate>(); factory.registerFunction<FunctionNegate>();
factory.registerFunction<FunctionAbs>();
factory.registerFunction<FunctionBitAnd>(); factory.registerFunction<FunctionBitAnd>();
factory.registerFunction<FunctionBitOr>(); factory.registerFunction<FunctionBitOr>();
factory.registerFunction<FunctionBitXor>(); factory.registerFunction<FunctionBitXor>();