xref: /freebsd/contrib/llvm-project/llvm/include/llvm/ADT/SlowDynamicAPInt.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1 //===- SlowDynamicAPInt.h - SlowDynamicAPInt Class --------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This is a simple class to represent arbitrary precision signed integers.
10 // Unlike APInt, one does not have to specify a fixed maximum size, and the
11 // integer can take on any arbitrary values.
12 //
13 // This class is to be used as a fallback slow path for the DynamicAPInt class,
14 // and is not intended to be used directly.
15 //
16 //===----------------------------------------------------------------------===//
17 
18 #ifndef LLVM_ADT_SLOWDYNAMICAPINT_H
19 #define LLVM_ADT_SLOWDYNAMICAPINT_H
20 
21 #include "llvm/ADT/APInt.h"
22 #include "llvm/Support/raw_ostream.h"
23 
24 namespace llvm {
25 class DynamicAPInt;
26 } // namespace llvm
27 
28 namespace llvm::detail {
29 /// A simple class providing dynamic arbitrary-precision arithmetic. Internally,
30 /// it stores an APInt, whose width is doubled whenever an overflow occurs at a
31 /// certain width. The default constructor sets the initial width to 64.
32 /// SlowDynamicAPInt is primarily intended to be used as a slow fallback path
33 /// for the upcoming DynamicAPInt class.
34 class SlowDynamicAPInt {
35   APInt Val;
36 
37 public:
38   explicit SlowDynamicAPInt(int64_t Val);
39   SlowDynamicAPInt();
40   explicit SlowDynamicAPInt(const APInt &Val);
41   SlowDynamicAPInt &operator=(int64_t Val);
42   explicit operator int64_t() const;
43   SlowDynamicAPInt operator-() const;
44   bool operator==(const SlowDynamicAPInt &O) const;
45   bool operator!=(const SlowDynamicAPInt &O) const;
46   bool operator>(const SlowDynamicAPInt &O) const;
47   bool operator<(const SlowDynamicAPInt &O) const;
48   bool operator<=(const SlowDynamicAPInt &O) const;
49   bool operator>=(const SlowDynamicAPInt &O) const;
50   SlowDynamicAPInt operator+(const SlowDynamicAPInt &O) const;
51   SlowDynamicAPInt operator-(const SlowDynamicAPInt &O) const;
52   SlowDynamicAPInt operator*(const SlowDynamicAPInt &O) const;
53   SlowDynamicAPInt operator/(const SlowDynamicAPInt &O) const;
54   SlowDynamicAPInt operator%(const SlowDynamicAPInt &O) const;
55   SlowDynamicAPInt &operator+=(const SlowDynamicAPInt &O);
56   SlowDynamicAPInt &operator-=(const SlowDynamicAPInt &O);
57   SlowDynamicAPInt &operator*=(const SlowDynamicAPInt &O);
58   SlowDynamicAPInt &operator/=(const SlowDynamicAPInt &O);
59   SlowDynamicAPInt &operator%=(const SlowDynamicAPInt &O);
60 
61   SlowDynamicAPInt &operator++();
62   SlowDynamicAPInt &operator--();
63 
64   friend SlowDynamicAPInt abs(const SlowDynamicAPInt &X);
65   friend SlowDynamicAPInt ceilDiv(const SlowDynamicAPInt &LHS,
66                                   const SlowDynamicAPInt &RHS);
67   friend SlowDynamicAPInt floorDiv(const SlowDynamicAPInt &LHS,
68                                    const SlowDynamicAPInt &RHS);
69   /// The operands must be non-negative for gcd.
70   friend SlowDynamicAPInt gcd(const SlowDynamicAPInt &A,
71                               const SlowDynamicAPInt &B);
72 
73   /// Overload to compute a hash_code for a SlowDynamicAPInt value.
74   friend hash_code hash_value(const SlowDynamicAPInt &X); // NOLINT
75 
76   // Make DynamicAPInt a friend so it can access Val directly.
77   friend DynamicAPInt;
78 
getBitWidth()79   unsigned getBitWidth() const { return Val.getBitWidth(); }
80 
81   void print(raw_ostream &OS) const;
82   LLVM_DUMP_METHOD void dump() const;
83 };
84 
85 inline raw_ostream &operator<<(raw_ostream &OS, const SlowDynamicAPInt &X) {
86   X.print(OS);
87   return OS;
88 }
89 
90 /// Returns the remainder of dividing LHS by RHS.
91 ///
92 /// The RHS is always expected to be positive, and the result
93 /// is always non-negative.
94 SlowDynamicAPInt mod(const SlowDynamicAPInt &LHS, const SlowDynamicAPInt &RHS);
95 
96 /// Returns the least common multiple of A and B.
97 SlowDynamicAPInt lcm(const SlowDynamicAPInt &A, const SlowDynamicAPInt &B);
98 
99 /// Redeclarations of friend declarations above to
100 /// make it discoverable by lookups.
101 SlowDynamicAPInt abs(const SlowDynamicAPInt &X);
102 SlowDynamicAPInt ceilDiv(const SlowDynamicAPInt &LHS,
103                          const SlowDynamicAPInt &RHS);
104 SlowDynamicAPInt floorDiv(const SlowDynamicAPInt &LHS,
105                           const SlowDynamicAPInt &RHS);
106 SlowDynamicAPInt gcd(const SlowDynamicAPInt &A, const SlowDynamicAPInt &B);
107 hash_code hash_value(const SlowDynamicAPInt &X); // NOLINT
108 
109 /// ---------------------------------------------------------------------------
110 /// Convenience operator overloads for int64_t.
111 /// ---------------------------------------------------------------------------
112 SlowDynamicAPInt &operator+=(SlowDynamicAPInt &A, int64_t B);
113 SlowDynamicAPInt &operator-=(SlowDynamicAPInt &A, int64_t B);
114 SlowDynamicAPInt &operator*=(SlowDynamicAPInt &A, int64_t B);
115 SlowDynamicAPInt &operator/=(SlowDynamicAPInt &A, int64_t B);
116 SlowDynamicAPInt &operator%=(SlowDynamicAPInt &A, int64_t B);
117 
118 bool operator==(const SlowDynamicAPInt &A, int64_t B);
119 bool operator!=(const SlowDynamicAPInt &A, int64_t B);
120 bool operator>(const SlowDynamicAPInt &A, int64_t B);
121 bool operator<(const SlowDynamicAPInt &A, int64_t B);
122 bool operator<=(const SlowDynamicAPInt &A, int64_t B);
123 bool operator>=(const SlowDynamicAPInt &A, int64_t B);
124 SlowDynamicAPInt operator+(const SlowDynamicAPInt &A, int64_t B);
125 SlowDynamicAPInt operator-(const SlowDynamicAPInt &A, int64_t B);
126 SlowDynamicAPInt operator*(const SlowDynamicAPInt &A, int64_t B);
127 SlowDynamicAPInt operator/(const SlowDynamicAPInt &A, int64_t B);
128 SlowDynamicAPInt operator%(const SlowDynamicAPInt &A, int64_t B);
129 
130 bool operator==(int64_t A, const SlowDynamicAPInt &B);
131 bool operator!=(int64_t A, const SlowDynamicAPInt &B);
132 bool operator>(int64_t A, const SlowDynamicAPInt &B);
133 bool operator<(int64_t A, const SlowDynamicAPInt &B);
134 bool operator<=(int64_t A, const SlowDynamicAPInt &B);
135 bool operator>=(int64_t A, const SlowDynamicAPInt &B);
136 SlowDynamicAPInt operator+(int64_t A, const SlowDynamicAPInt &B);
137 SlowDynamicAPInt operator-(int64_t A, const SlowDynamicAPInt &B);
138 SlowDynamicAPInt operator*(int64_t A, const SlowDynamicAPInt &B);
139 SlowDynamicAPInt operator/(int64_t A, const SlowDynamicAPInt &B);
140 SlowDynamicAPInt operator%(int64_t A, const SlowDynamicAPInt &B);
141 } // namespace llvm::detail
142 
143 #endif // LLVM_ADT_SLOWDYNAMICAPINT_H
144