CNL  2.0.2 (development)
Compositional Numeric Library
modulo.h
1 
2 // Copyright John McFarlane 2019.
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 
7 #if !defined(CNL_IMPL_DUPLEX_INTEGER_MODULO_H)
8 #define CNL_IMPL_DUPLEX_INTEGER_MODULO_H
9 
10 #include "../../wide_integer.h"
11 #include "../custom_operator/definition.h"
12 #include "../custom_operator/op.h"
13 #include "definition.h"
14 #include "numbers.h"
15 
16 #include <algorithm>
17 
19 namespace cnl {
20  namespace _impl {
21  // cnl::_impl::heterogeneous_duplex_modulo_operator
22  template<typename Lhs, typename Rhs>
23  struct heterogeneous_duplex_modulo_operator {
24  using common_type = rep_of_t<wide_integer<
25  std::max(digits_v<Lhs>, digits_v<Rhs>),
26  numbers::set_signedness_t<int, numbers::signedness_v<Lhs> | numbers::signedness_v<Rhs>>>>;
27 
28  [[nodiscard]] constexpr auto operator()(Lhs const& lhs, Rhs const& rhs) const -> Lhs
29  {
30  return static_cast<Lhs>(
31  static_cast<common_type>(lhs) / static_cast<common_type>(rhs));
32  }
33  };
34  }
35 
36  // duplex_integer<> % duplex_integer<>
37  template<typename Upper, typename Lower>
38  struct custom_operator<
39  _impl::modulo_op,
40  op_value<_impl::duplex_integer<Upper, Lower>>,
41  op_value<_impl::duplex_integer<Upper, Lower>>> {
42  private:
43  using duplex_integer = _impl::duplex_integer<Upper, Lower>;
44 
45  public:
46  [[nodiscard]] constexpr auto operator()(
47  duplex_integer const& lhs, duplex_integer const& rhs) const -> duplex_integer
48  {
49  return lhs - rhs * (lhs / rhs);
50  }
51  };
52 
53  template<typename LhsUpper, typename LhsLower, typename RhsUpper, typename RhsLower>
54  struct custom_operator<
55  _impl::modulo_op,
56  op_value<_impl::duplex_integer<LhsUpper, LhsLower>>,
57  op_value<_impl::duplex_integer<RhsUpper, RhsLower>>>
58  : _impl::heterogeneous_duplex_modulo_operator<
59  _impl::duplex_integer<LhsUpper, LhsLower>,
60  _impl::duplex_integer<RhsUpper, RhsLower>> {
61  };
62 
63  template<typename Lhs, typename RhsUpper, typename RhsLower>
64  struct custom_operator<
65  _impl::modulo_op,
66  op_value<Lhs>,
67  op_value<_impl::duplex_integer<RhsUpper, RhsLower>>>
68  : _impl::heterogeneous_duplex_modulo_operator<
69  Lhs, _impl::duplex_integer<RhsUpper, RhsLower>> {
70  };
71 
72  template<typename LhsUpper, typename LhsLower, typename Rhs>
73  struct custom_operator<
74  _impl::modulo_op,
75  op_value<_impl::duplex_integer<LhsUpper, LhsLower>>,
76  op_value<Rhs>>
77  : _impl::heterogeneous_duplex_modulo_operator<
78  _impl::duplex_integer<LhsUpper, LhsLower>, Rhs> {
79  };
80 }
81 
82 #endif // CNL_IMPL_DUPLEX_INTEGER_MODULO_H
numbers.h
cnl::wide_integer
_impl::wrapper< typename wide_tag< Digits, Narrowest >::rep, wide_tag< Digits, Narrowest > > wide_integer
An integer of limitless width.
Definition: definition.h:19
cnl
compositional numeric library
Definition: abort.h:15
std::max
T max(T... args)