1 | //===----------------------------------------------------------------------===// |
2 | // DuckDB |
3 | // |
4 | // duckdb/common/operator/abs.hpp |
5 | // |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #pragma once |
10 | |
11 | #include "duckdb/common/types.hpp" |
12 | #include "duckdb/common/exception.hpp" |
13 | #include "duckdb/common/limits.hpp" |
14 | |
15 | namespace duckdb { |
16 | |
17 | struct AbsOperator { |
18 | template <class TA, class TR> |
19 | static inline TR Operation(TA input) { |
20 | return input < 0 ? -input : input; |
21 | } |
22 | }; |
23 | |
24 | template <> |
25 | inline hugeint_t AbsOperator::Operation(hugeint_t input) { |
26 | const hugeint_t zero(0); |
27 | return (input < zero) ? -input : input; |
28 | } |
29 | |
30 | struct TryAbsOperator { |
31 | template <class TA, class TR> |
32 | static inline TR Operation(TA input) { |
33 | return AbsOperator::Operation<TA, TR>(input); |
34 | } |
35 | }; |
36 | |
37 | template <> |
38 | inline int8_t TryAbsOperator::Operation(int8_t input) { |
39 | if (input == NumericLimits<int8_t>::Minimum()) { |
40 | throw OutOfRangeException("Overflow on abs(%d)" , input); |
41 | } |
42 | return input < 0 ? -input : input; |
43 | } |
44 | |
45 | template <> |
46 | inline int16_t TryAbsOperator::Operation(int16_t input) { |
47 | if (input == NumericLimits<int16_t>::Minimum()) { |
48 | throw OutOfRangeException("Overflow on abs(%d)" , input); |
49 | } |
50 | return input < 0 ? -input : input; |
51 | } |
52 | |
53 | template <> |
54 | inline int32_t TryAbsOperator::Operation(int32_t input) { |
55 | if (input == NumericLimits<int32_t>::Minimum()) { |
56 | throw OutOfRangeException("Overflow on abs(%d)" , input); |
57 | } |
58 | return input < 0 ? -input : input; |
59 | } |
60 | |
61 | template <> |
62 | inline int64_t TryAbsOperator::Operation(int64_t input) { |
63 | if (input == NumericLimits<int64_t>::Minimum()) { |
64 | throw OutOfRangeException("Overflow on abs(%d)" , input); |
65 | } |
66 | return input < 0 ? -input : input; |
67 | } |
68 | |
69 | template <> |
70 | inline dtime_t TryAbsOperator::Operation(dtime_t input) { |
71 | return dtime_t(TryAbsOperator::Operation<int64_t, int64_t>(input: input.micros)); |
72 | } |
73 | |
74 | template <> |
75 | inline interval_t TryAbsOperator::Operation(interval_t input) { |
76 | return {.months: TryAbsOperator::Operation<int32_t, int32_t>(input: input.months), |
77 | .days: TryAbsOperator::Operation<int32_t, int32_t>(input: input.days), |
78 | .micros: TryAbsOperator::Operation<int64_t, int64_t>(input: input.micros)}; |
79 | } |
80 | |
81 | } // namespace duckdb |
82 | |