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
15namespace duckdb {
16
17struct AbsOperator {
18 template <class TA, class TR>
19 static inline TR Operation(TA input) {
20 return input < 0 ? -input : input;
21 }
22};
23
24template <>
25inline hugeint_t AbsOperator::Operation(hugeint_t input) {
26 const hugeint_t zero(0);
27 return (input < zero) ? -input : input;
28}
29
30struct TryAbsOperator {
31 template <class TA, class TR>
32 static inline TR Operation(TA input) {
33 return AbsOperator::Operation<TA, TR>(input);
34 }
35};
36
37template <>
38inline 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
45template <>
46inline 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
53template <>
54inline 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
61template <>
62inline 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
69template <>
70inline dtime_t TryAbsOperator::Operation(dtime_t input) {
71 return dtime_t(TryAbsOperator::Operation<int64_t, int64_t>(input: input.micros));
72}
73
74template <>
75inline 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