CNL  2.0.2 (development)
Compositional Numeric Library
operators.h
Go to the documentation of this file.
1 
2 // Copyright John McFarlane 2015 - 2016.
3 // Distributed under the Boost Software License, Version 1.0.
4 // (See accompanying file ../LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6 
9 
10 #if !defined(CNL_IMPL_SCALED_INTEGER_OPERATORS_H)
11 #define CNL_IMPL_SCALED_INTEGER_OPERATORS_H
12 
13 #include "../narrow_cast.h"
14 #include "../scaled/power.h"
15 #include "definition.h"
16 
17 #include <numeric>
18 
20 namespace cnl {
22  // heterogeneous operator overloads
23 
24  // comparison between operands with different rep and exponent
25  template<
26  _impl::comparison_op Operator,
27  typename LhsRep, int LhsExponent,
28  typename RhsRep, int RhsExponent,
29  int Radix>
30  requires(LhsExponent < RhsExponent) struct custom_operator<
31  Operator,
32  op_value<scaled_integer<LhsRep, power<LhsExponent, Radix>>>,
33  op_value<scaled_integer<RhsRep, power<RhsExponent, Radix>>>> {
34  static constexpr int shiftage = RhsExponent - LhsExponent;
35  using lhs_type = scaled_integer<LhsRep, power<LhsExponent, Radix>>;
36  using rhs_type = scaled_integer<
37  decltype(std::declval<RhsRep>() << constant<shiftage>()),
38  power<LhsExponent, Radix>>;
39 
40  [[nodiscard]] constexpr auto operator()(
41  scaled_integer<LhsRep, power<LhsExponent, Radix>> const& lhs,
42  scaled_integer<RhsRep, power<RhsExponent, Radix>> const& rhs) const
43  {
44  return _impl::operate<Operator>{}(lhs_type{lhs}, rhs_type{rhs});
45  }
46  };
47 
48  template<
49  _impl::comparison_op Operator,
50  typename LhsRep, int LhsExponent,
51  typename RhsRep, int RhsExponent,
52  int Radix>
53  requires(RhsExponent < LhsExponent) struct custom_operator<
54  Operator,
55  op_value<scaled_integer<LhsRep, power<LhsExponent, Radix>>>,
56  op_value<scaled_integer<RhsRep, power<RhsExponent, Radix>>>> {
57  static constexpr int shiftage = LhsExponent - RhsExponent;
58  using lhs_type = scaled_integer<
59  decltype(std::declval<LhsRep>() << constant<shiftage>()),
60  power<RhsExponent, Radix>>;
61  using rhs_type = scaled_integer<RhsRep, power<RhsExponent, Radix>>;
62 
63  [[nodiscard]] constexpr auto operator()(
64  scaled_integer<LhsRep, power<LhsExponent, Radix>> const& lhs,
65  scaled_integer<RhsRep, power<RhsExponent, Radix>> const& rhs) const
66  {
67  return _impl::operate<Operator>{}(lhs_type{lhs}, rhs_type{rhs});
68  }
69  };
70 
72  // shift operators
73 
74  // scaled_integer << constant
75  template<typename LhsRep, int LhsExponent, int LhsRadix, CNL_IMPL_CONSTANT_VALUE_TYPE RhsValue>
76  struct custom_operator<
77  _impl::shift_left_op,
78  op_value<scaled_integer<LhsRep, power<LhsExponent, LhsRadix>>>,
79  op_value<constant<RhsValue>>> {
80  using result_type = scaled_integer<LhsRep, power<LhsExponent + _impl::narrow_cast<int>(RhsValue), LhsRadix>>;
81  [[nodiscard]] constexpr auto operator()(
82  scaled_integer<LhsRep, power<LhsExponent, LhsRadix>> const& lhs,
83  constant<RhsValue>) const
84  {
85  return _impl::from_rep<result_type>(_impl::to_rep(lhs));
86  };
87  };
88 
89  // scaled_integer >> constant
90  template<typename LhsRep, int LhsExponent, int LhsRadix, CNL_IMPL_CONSTANT_VALUE_TYPE RhsValue>
91  struct custom_operator<
92  _impl::shift_right_op,
93  op_value<scaled_integer<LhsRep, power<LhsExponent, LhsRadix>>>,
94  op_value<constant<RhsValue>>> {
95  using result_type = scaled_integer<LhsRep, power<LhsExponent - _impl::narrow_cast<int>(RhsValue), LhsRadix>>;
96  [[nodiscard]] constexpr auto operator()(
97  scaled_integer<LhsRep, power<LhsExponent, LhsRadix>> const& lhs,
98  constant<RhsValue>) const
99  {
100  return _impl::from_rep<result_type>(_impl::to_rep(lhs));
101  };
102  };
103 }
104 
105 #endif // CNL_IMPL_SCALED_INTEGER_OPERATORS_H
cnl
compositional numeric library
Definition: abort.h:15
cnl::scaled_integer
_impl::wrapper< Rep, Scale > scaled_integer
literal real number approximation that uses fixed-point arithmetic
Definition: definition.h:52