7 #if !defined(CNL_IMPL_TAG_TAG_OVERLOADS_H)
8 #define CNL_IMPL_TAG_TAG_OVERLOADS_H
10 #include "../num_traits/set_width.h"
11 #include "../num_traits/width.h"
12 #include "../numbers/set_signedness.h"
13 #include "../numbers/signedness.h"
14 #include "definition.h"
22 binary_arithmetic_op Operator,
int LhsDigits,
typename LhsNarrowest,
int RhsDigits,
23 typename RhsNarrowest>
24 struct wide_tag_overload_params {
25 static constexpr
bool is_signed{
26 numbers::signedness_v<LhsNarrowest> | numbers::signedness_v<RhsNarrowest>};
27 static constexpr
int digits{
std::max(LhsDigits, RhsDigits)};
29 using narrowest = _impl::set_width_t<
30 numbers::set_signedness_t<
31 _impl::op_result<Operator, LhsNarrowest, RhsNarrowest>, is_signed>,
33 _impl::width<LhsNarrowest>, _impl::width<RhsNarrowest>)>;
35 using type = cnl::wide_tag<digits, narrowest>;
39 template<
int LhsDigits,
typename LhsNarrowest,
int RhsDigits,
typename RhsNarrowest>
40 [[nodiscard]] constexpr
auto operator+(
41 cnl::wide_tag<LhsDigits, LhsNarrowest>, cnl::wide_tag<RhsDigits, RhsNarrowest>) ->
42 typename _impl::wide_tag_overload_params<
43 _impl::add_op, LhsDigits, LhsNarrowest, RhsDigits, RhsNarrowest>::type
45 return typename _impl::wide_tag_overload_params<
46 _impl::add_op, LhsDigits, LhsNarrowest, RhsDigits, RhsNarrowest>::type{};
49 template<
int LhsDigits,
typename LhsNarrowest,
int RhsDigits,
typename RhsNarrowest>
50 [[nodiscard]] constexpr
auto operator-(
51 cnl::wide_tag<LhsDigits, LhsNarrowest>, cnl::wide_tag<RhsDigits, RhsNarrowest>) ->
52 typename _impl::wide_tag_overload_params<
53 _impl::subtract_op, LhsDigits, LhsNarrowest, RhsDigits, RhsNarrowest>::type
55 return typename _impl::wide_tag_overload_params<
56 _impl::subtract_op, LhsDigits, LhsNarrowest, RhsDigits, RhsNarrowest>::type{};
59 template<
int LhsDigits,
typename LhsNarrowest,
int RhsDigits,
typename RhsNarrowest>
60 [[nodiscard]] constexpr
auto operator*(
61 cnl::wide_tag<LhsDigits, LhsNarrowest>, cnl::wide_tag<RhsDigits, RhsNarrowest>) ->
62 typename _impl::wide_tag_overload_params<
63 _impl::multiply_op, LhsDigits, LhsNarrowest, RhsDigits, RhsNarrowest>::type
65 return typename _impl::wide_tag_overload_params<
66 _impl::multiply_op, LhsDigits, LhsNarrowest, RhsDigits, RhsNarrowest>::type{};
69 template<
int LhsDigits,
typename LhsNarrowest,
int RhsDigits,
typename RhsNarrowest>
70 [[nodiscard]] constexpr
auto operator/(
71 cnl::wide_tag<LhsDigits, LhsNarrowest>, cnl::wide_tag<RhsDigits, RhsNarrowest>) ->
72 typename _impl::wide_tag_overload_params<
73 _impl::divide_op, LhsDigits, LhsNarrowest, RhsDigits, RhsNarrowest>::type
75 return typename _impl::wide_tag_overload_params<
76 _impl::divide_op, LhsDigits, LhsNarrowest, RhsDigits, RhsNarrowest>::type{};
79 template<
int LhsDigits,
typename LhsNarrowest,
int RhsDigits,
typename RhsNarrowest>
80 [[nodiscard]] constexpr
auto operator%(
81 cnl::wide_tag<LhsDigits, LhsNarrowest>, cnl::wide_tag<RhsDigits, RhsNarrowest>) ->
82 typename _impl::wide_tag_overload_params<
83 _impl::modulo_op, LhsDigits, LhsNarrowest, RhsDigits, RhsNarrowest>::type
85 return typename _impl::wide_tag_overload_params<
86 _impl::modulo_op, LhsDigits, LhsNarrowest, RhsDigits, RhsNarrowest>::type{};
89 template<
int LhsDigits,
typename LhsNarrowest,
int RhsDigits,
typename RhsNarrowest>
90 [[nodiscard]] constexpr
auto operator&(
91 cnl::wide_tag<LhsDigits, LhsNarrowest>, cnl::wide_tag<RhsDigits, RhsNarrowest>) ->
92 typename _impl::wide_tag_overload_params<
93 _impl::bitwise_and_op, LhsDigits, LhsNarrowest, RhsDigits, RhsNarrowest>::type
95 return typename _impl::wide_tag_overload_params<
96 _impl::bitwise_and_op, LhsDigits, LhsNarrowest, RhsDigits, RhsNarrowest>::type{};
100 #endif // CNL_IMPL_TAG_TAG_OVERLOADS_H