7 #if !defined(CNL_IMPL_OVERFLOW_BUILTIN_OVERFLOW_H)
8 #define CNL_IMPL_OVERFLOW_BUILTIN_OVERFLOW_H
10 #include "../config.h"
11 #include "../custom_operator/op.h"
12 #include "../polarity.h"
13 #include "overflow_operator.h"
24 struct overflow_polarity;
27 struct overflow_polarity<convert_op> {
28 template<
typename Destination,
typename Source>
29 [[nodiscard]] constexpr
auto operator()(Source
const& from)
const
31 return measure_polarity(from);
36 struct overflow_polarity<minus_op> {
37 template<
typename Rhs>
38 [[nodiscard]] constexpr
auto operator()(Rhs
const& rhs)
const
40 return -measure_polarity(rhs);
45 struct overflow_polarity<add_op> {
46 template<
typename Lhs,
typename Rhs>
47 [[nodiscard]] constexpr
auto operator()(Lhs
const&, Rhs
const& rhs)
const
49 return measure_polarity(rhs);
54 struct overflow_polarity<subtract_op> {
55 template<
typename Lhs,
typename Rhs>
56 [[nodiscard]] constexpr
auto operator()(Lhs
const&, Rhs
const& rhs)
const
58 return -measure_polarity(rhs);
63 struct overflow_polarity<multiply_op> {
64 template<
typename Lhs,
typename Rhs>
65 [[nodiscard]] constexpr
auto operator()(Lhs
const& lhs, Rhs
const& rhs)
const
67 return measure_polarity(lhs) * measure_polarity(rhs);
74 template<
typename Lhs,
typename Rhs>
75 struct are_builtin_operands
77 bool, std::is_integral_v<Lhs> && std::is_integral_v<Rhs>> {
83 template<binary_arithmetic_op Operator,
typename Lhs,
typename Rhs>
87 #if defined(CNL_BUILTIN_OVERFLOW_ENABLED)
88 template<
typename Lhs,
typename Rhs>
89 struct builtin_overflow_operator<add_op, Lhs, Rhs> : are_builtin_operands<Lhs, Rhs> {
90 template<
typename Result>
91 [[nodiscard]] constexpr
auto operator()(
92 Lhs
const& lhs, Rhs
const& rhs, Result& result)
const
94 return __builtin_add_overflow(lhs, rhs, &result);
98 template<
typename Lhs,
typename Rhs>
99 struct builtin_overflow_operator<subtract_op, Lhs, Rhs> : are_builtin_operands<Lhs, Rhs> {
100 template<
typename Result>
101 [[nodiscard]] constexpr
auto operator()(
102 Lhs
const& lhs, Rhs
const& rhs, Result& result)
const
104 return __builtin_sub_overflow(lhs, rhs, &result);
108 template<
typename Lhs,
typename Rhs>
109 struct builtin_overflow_operator<multiply_op, Lhs, Rhs> : are_builtin_operands<Lhs, Rhs> {
110 template<
typename Result>
111 [[nodiscard]] constexpr
auto operator()(
112 Lhs
const& lhs, Rhs
const& rhs, Result& result)
const
114 return __builtin_mul_overflow(lhs, rhs, &result);
121 #endif // CNL_IMPL_OVERFLOW_BUILTIN_OVERFLOW_H