Mantid
Loading...
Searching...
No Matches
WideInt.h
Go to the documentation of this file.
1#pragma once
2
4// Distributed under the Boost Software License, Version 1.0.
5// (See at http://www.boost.org/LICENSE_1_0.txt)
7
8/* Divide and multiply
9 *
10 *
11 * Copyright (c) 2008
12 * Evan Teran
13 *
14 * Permission to use, copy, modify, and distribute this software and its
15 * documentation for any purpose and without fee is hereby granted, provided
16 * that the above copyright notice appears in all copies and that both the
17 * copyright notice and this permission notice appear in supporting
18 * documentation, and that the same name not be used in advertising or
19 * publicity pertaining to distribution of the software without specific,
20 * written prior permission. We make no representations about the
21 * suitability this software for any purpose. It is provided "as is"
22 * without express or implied warranty.
23 */
24
25#include <climits> // CHAR_BIT
26#include <cmath>
27#include <cstdint>
28#include <iomanip>
29#include <limits>
30#include <ostream>
31#include <sstream>
32#include <stdexcept>
33#include <stdint.h>
34#include <system_error>
35#include <type_traits>
36
60namespace std {
61template <size_t Bits, typename Signed> class wide_integer;
62
63template <size_t Bits, typename Signed, size_t Bits2, typename Signed2>
64struct common_type<wide_integer<Bits, Signed>, wide_integer<Bits2, Signed2>>;
65
66template <size_t Bits, typename Signed, typename Arithmetic> struct common_type<wide_integer<Bits, Signed>, Arithmetic>;
67
68template <typename Arithmetic, size_t Bits, typename Signed> struct common_type<Arithmetic, wide_integer<Bits, Signed>>;
69
70template <size_t Bits, typename Signed> class wide_integer {
71public:
72 using base_type = uint32_t;
73 using signed_base_type = int32_t;
74
75 // ctors
76 wide_integer() = default;
77
78 template <typename T> constexpr wide_integer(T rhs) noexcept;
79 template <size_t Bits2, typename Signed2> constexpr wide_integer(const wide_integer<Bits2, Signed2> &rhs) noexcept;
80
81 // assignment
82 template <size_t Bits2, typename Signed2>
84
85 template <typename Arithmetic> constexpr wide_integer<Bits, Signed> &operator=(Arithmetic rhs) noexcept;
86
87 template <typename Arithmetic> constexpr wide_integer<Bits, Signed> &operator*=(const Arithmetic &rhs);
88
89 template <typename Arithmetic> constexpr wide_integer<Bits, Signed> &operator/=(const Arithmetic &rhs);
90
91 template <typename Arithmetic>
92 constexpr wide_integer<Bits, Signed> &operator+=(const Arithmetic &rhs) noexcept(is_same<Signed, unsigned>::value);
93
94 template <typename Arithmetic>
95 constexpr wide_integer<Bits, Signed> &operator-=(const Arithmetic &rhs) noexcept(is_same<Signed, unsigned>::value);
96
97 template <typename Integral> constexpr wide_integer<Bits, Signed> &operator%=(const Integral &rhs);
98
99 template <typename Integral> constexpr wide_integer<Bits, Signed> &operator&=(const Integral &rhs) noexcept;
100
101 template <typename Integral> constexpr wide_integer<Bits, Signed> &operator|=(const Integral &rhs) noexcept;
102
103 template <typename Integral> constexpr wide_integer<Bits, Signed> &operator^=(const Integral &rhs) noexcept;
104
105 template <typename T2, typename = std::enable_if<std::is_integral<T2>::value && std::is_unsigned<T2>::value>>
106 constexpr wide_integer<Bits, Signed> &operator<<=(T2 n) noexcept;
107 template <typename T2, typename = std::enable_if<std::is_integral<T2>::value && std::is_unsigned<T2>::value>>
108 constexpr wide_integer<Bits, Signed> &operator>>=(T2 n) noexcept;
109
110 constexpr wide_integer<Bits, Signed> &operator++() noexcept(is_same<Signed, unsigned>::value);
111 constexpr wide_integer<Bits, Signed> operator++(int) noexcept(is_same<Signed, unsigned>::value);
112 constexpr wide_integer<Bits, Signed> &operator--() noexcept(is_same<Signed, unsigned>::value);
113 constexpr wide_integer<Bits, Signed> operator--(int) noexcept(is_same<Signed, unsigned>::value);
114
115 // observers
116
117 constexpr explicit operator bool() const noexcept;
118
119 template <class T>
120 using __integral_not_wide_integer_class = typename std::enable_if<std::is_arithmetic<T>::value, T>::type;
121
122 template <class T, class = __integral_not_wide_integer_class<T>> constexpr operator T() const noexcept;
123
124 constexpr operator long double() const noexcept;
125 constexpr operator double() const noexcept;
126 constexpr operator float() const noexcept;
127
128 struct _impl;
129 const base_type *ptr() const { return m_arr; }
130 base_type *ptr() { return m_arr; }
131
132private:
133 template <size_t Bits2, typename Signed2> friend class wide_integer;
134
135 friend class numeric_limits<wide_integer<Bits, signed>>;
136 friend class numeric_limits<wide_integer<Bits, unsigned>>;
137
138 base_type m_arr[_impl::arr_size];
139};
140
141template <typename T> static constexpr bool ArithmeticConcept() noexcept;
142template <class T1, class T2>
143using __only_arithmetic = typename std::enable_if<ArithmeticConcept<T1>() && ArithmeticConcept<T2>()>::type;
144
145template <typename T> static constexpr bool IntegralConcept() noexcept;
146template <class T, class T2>
147using __only_integer = typename std::enable_if<IntegralConcept<T>() && IntegralConcept<T2>()>::type;
148
149// Unary operators
150template <size_t Bits, typename Signed>
151constexpr wide_integer<Bits, Signed> operator~(const wide_integer<Bits, Signed> &lhs) noexcept;
152
153template <size_t Bits, typename Signed>
154constexpr wide_integer<Bits, Signed>
155operator-(const wide_integer<Bits, Signed> &lhs) noexcept(is_same<Signed, unsigned>::value);
156
157template <size_t Bits, typename Signed>
158constexpr wide_integer<Bits, Signed>
159operator+(const wide_integer<Bits, Signed> &lhs) noexcept(is_same<Signed, unsigned>::value);
160
161// Binary operators
162template <size_t Bits, typename Signed, size_t Bits2, typename Signed2>
163std::common_type_t<wide_integer<Bits, Signed>, wide_integer<Bits2, Signed2>> constexpr
164operator*(const wide_integer<Bits, Signed> &lhs, const wide_integer<Bits2, Signed2> &rhs);
165template <typename Arithmetic, typename Arithmetic2, class = __only_arithmetic<Arithmetic, Arithmetic2>>
166std::common_type_t<Arithmetic, Arithmetic2> constexpr operator*(const Arithmetic &rhs, const Arithmetic2 &lhs);
167
168template <size_t Bits, typename Signed, size_t Bits2, typename Signed2>
169std::common_type_t<wide_integer<Bits, Signed>, wide_integer<Bits2, Signed2>> constexpr
170operator/(const wide_integer<Bits, Signed> &lhs, const wide_integer<Bits2, Signed2> &rhs);
171template <typename Arithmetic, typename Arithmetic2, class = __only_arithmetic<Arithmetic, Arithmetic2>>
172std::common_type_t<Arithmetic, Arithmetic2> constexpr operator/(const Arithmetic &rhs, const Arithmetic2 &lhs);
173
174template <size_t Bits, typename Signed, size_t Bits2, typename Signed2>
175std::common_type_t<wide_integer<Bits, Signed>, wide_integer<Bits2, Signed2>> constexpr
176operator+(const wide_integer<Bits, Signed> &lhs, const wide_integer<Bits2, Signed2> &rhs);
177template <typename Arithmetic, typename Arithmetic2, class = __only_arithmetic<Arithmetic, Arithmetic2>>
178std::common_type_t<Arithmetic, Arithmetic2> constexpr operator+(const Arithmetic &rhs, const Arithmetic2 &lhs);
179
180template <size_t Bits, typename Signed, size_t Bits2, typename Signed2>
181std::common_type_t<wide_integer<Bits, Signed>, wide_integer<Bits2, Signed2>> constexpr
182operator-(const wide_integer<Bits, Signed> &lhs, const wide_integer<Bits2, Signed2> &rhs);
183template <typename Arithmetic, typename Arithmetic2, class = __only_arithmetic<Arithmetic, Arithmetic2>>
184std::common_type_t<Arithmetic, Arithmetic2> constexpr operator-(const Arithmetic &rhs, const Arithmetic2 &lhs);
185
186template <size_t Bits, typename Signed, size_t Bits2, typename Signed2>
187std::common_type_t<wide_integer<Bits, Signed>, wide_integer<Bits2, Signed2>> constexpr
188operator%(const wide_integer<Bits, Signed> &lhs, const wide_integer<Bits2, Signed2> &rhs);
189template <typename Integral, typename Integral2, class = __only_integer<Integral, Integral2>>
190std::common_type_t<Integral, Integral2> constexpr operator%(const Integral &rhs, const Integral2 &lhs);
191
192template <size_t Bits, typename Signed, size_t Bits2, typename Signed2>
193std::common_type_t<wide_integer<Bits, Signed>, wide_integer<Bits2, Signed2>> constexpr
194operator&(const wide_integer<Bits, Signed> &lhs, const wide_integer<Bits2, Signed2> &rhs);
195template <typename Integral, typename Integral2, class = __only_integer<Integral, Integral2>>
196std::common_type_t<Integral, Integral2> constexpr operator&(const Integral &rhs, const Integral2 &lhs);
197
198template <size_t Bits, typename Signed, size_t Bits2, typename Signed2>
199std::common_type_t<wide_integer<Bits, Signed>, wide_integer<Bits2, Signed2>> constexpr
200operator|(const wide_integer<Bits, Signed> &lhs, const wide_integer<Bits2, Signed2> &rhs);
201template <typename Integral, typename Integral2, class = __only_integer<Integral, Integral2>>
202std::common_type_t<Integral, Integral2> constexpr operator|(const Integral &rhs, const Integral2 &lhs);
203
204template <size_t Bits, typename Signed, size_t Bits2, typename Signed2>
205std::common_type_t<wide_integer<Bits, Signed>, wide_integer<Bits2, Signed2>> constexpr
206operator^(const wide_integer<Bits, Signed> &lhs, const wide_integer<Bits2, Signed2> &rhs);
207template <typename Integral, typename Integral2, class = __only_integer<Integral, Integral2>>
208std::common_type_t<Integral, Integral2> constexpr operator^(const Integral &rhs, const Integral2 &lhs);
209
210// TODO: Integral
211template <size_t Bits, typename Signed, typename T2,
212 typename = std::enable_if<std::is_integral<T2>::value && std::is_unsigned<T2>::value>>
213constexpr wide_integer<Bits, Signed> operator<<(const wide_integer<Bits, Signed> &lhs, T2 n) noexcept;
214
215template <size_t Bits, typename Signed, typename T2,
216 typename = std::enable_if<std::is_integral<T2>::value && std::is_unsigned<T2>::value>>
217constexpr wide_integer<Bits, Signed> operator>>(const wide_integer<Bits, Signed> &lhs, T2 n) noexcept;
218
219template <size_t Bits, typename Signed, size_t Bits2, typename Signed2>
220constexpr bool operator<(const wide_integer<Bits, Signed> &lhs, const wide_integer<Bits2, Signed2> &rhs);
221template <typename Arithmetic, typename Arithmetic2, class = __only_arithmetic<Arithmetic, Arithmetic2>>
222constexpr bool operator<(const Arithmetic &rhs, const Arithmetic2 &lhs);
223
224template <size_t Bits, typename Signed, size_t Bits2, typename Signed2>
225constexpr bool operator>(const wide_integer<Bits, Signed> &lhs, const wide_integer<Bits2, Signed2> &rhs);
226template <typename Arithmetic, typename Arithmetic2, class = __only_arithmetic<Arithmetic, Arithmetic2>>
227constexpr bool operator>(const Arithmetic &rhs, const Arithmetic2 &lhs);
228
229template <size_t Bits, typename Signed, size_t Bits2, typename Signed2>
230constexpr bool operator<=(const wide_integer<Bits, Signed> &lhs, const wide_integer<Bits2, Signed2> &rhs);
231template <typename Arithmetic, typename Arithmetic2, class = __only_arithmetic<Arithmetic, Arithmetic2>>
232constexpr bool operator<=(const Arithmetic &rhs, const Arithmetic2 &lhs);
233
234template <size_t Bits, typename Signed, size_t Bits2, typename Signed2>
235constexpr bool operator>=(const wide_integer<Bits, Signed> &lhs, const wide_integer<Bits2, Signed2> &rhs);
236template <typename Arithmetic, typename Arithmetic2, class = __only_arithmetic<Arithmetic, Arithmetic2>>
237constexpr bool operator>=(const Arithmetic &rhs, const Arithmetic2 &lhs);
238
239template <size_t Bits, typename Signed, size_t Bits2, typename Signed2>
240constexpr bool operator==(const wide_integer<Bits, Signed> &lhs, const wide_integer<Bits2, Signed2> &rhs);
241template <typename Arithmetic, typename Arithmetic2, class = __only_arithmetic<Arithmetic, Arithmetic2>>
242constexpr bool operator==(const Arithmetic &rhs, const Arithmetic2 &lhs);
243
244template <size_t Bits, typename Signed, size_t Bits2, typename Signed2>
245constexpr bool operator!=(const wide_integer<Bits, Signed> &lhs, const wide_integer<Bits2, Signed2> &rhs);
246template <typename Arithmetic, typename Arithmetic2, class = __only_arithmetic<Arithmetic, Arithmetic2>>
247constexpr bool operator!=(const Arithmetic &rhs, const Arithmetic2 &lhs);
248
249template <size_t Bits, typename Signed> std::string to_string(const wide_integer<Bits, Signed> &n);
250
251template <size_t Bits, typename Signed> std::wstring to_wstring(const wide_integer<Bits, Signed> &n);
252
253template <size_t Bits, typename Signed>
254std::ostream &operator<<(std::ostream &out, const wide_integer<Bits, Signed> &n);
255
256template <size_t Bits, typename Signed>
257std::wostream &operator<<(std::wostream &out, const wide_integer<Bits, Signed> &n);
258
259template <size_t Bits, typename Signed> std::istream &operator>>(std::istream &in, wide_integer<Bits, Signed> &n);
260
261template <size_t Bits, typename Signed> std::wistream &operator>>(std::wistream &in, wide_integer<Bits, Signed> &n);
262
265 char *ptr;
266 std::error_code ec;
267};
268
270 const char *ptr;
271 std::error_code ec;
272};
274
275template <size_t Bits, typename Signed>
276to_chars_result to_chars(char *first, char *last, const wide_integer<Bits, Signed> &value, int base = 10);
277
278template <size_t Bits, typename Signed>
279from_chars_result from_chars(const char *first, const char *last, wide_integer<Bits, Signed> &value, int base = 10);
280
281inline namespace literals {
282inline namespace wide_integer_literals {
283template <size_t Bits> using wide_int = wide_integer<Bits, signed>;
284
285template <size_t Bits> using wide_uint = wide_integer<Bits, unsigned>;
286
289
292
295
296} // namespace wide_integer_literals
297} // namespace literals
298
299constexpr int128_t operator"" _cppi128(const char *n);
300constexpr int256_t operator"" _cppi256(const char *n);
301constexpr int512_t operator"" _cppi512(const char *n);
302constexpr uint128_t operator"" _cppui128(const char *n);
303constexpr uint256_t operator"" _cppui256(const char *n);
304constexpr uint512_t operator"" _cppui512(const char *n);
305
306// numeric limits
307template <size_t Bits, typename Signed> class numeric_limits<wide_integer<Bits, Signed>>;
308
309template <size_t Bits, typename Signed> struct hash<wide_integer<Bits, Signed>>;
310
311} // namespace std
312
313#include "WideIntImpl.h"
const std::vector< double > & rhs
double value
The value of the point.
Definition: FitMW.cpp:51
constexpr wide_integer< Bits, Signed > & operator>>=(T2 n) noexcept
const base_type * ptr() const
Definition: WideInt.h:129
constexpr wide_integer< Bits, Signed > & operator<<=(T2 n) noexcept
constexpr wide_integer< Bits, Signed > & operator++() noexcept(is_same< Signed, unsigned >::value)
constexpr wide_integer< Bits, Signed > & operator&=(const Integral &rhs) noexcept
base_type m_arr[_impl::arr_size]
Definition: WideInt.h:138
int32_t signed_base_type
Definition: WideInt.h:73
constexpr wide_integer(const wide_integer< Bits2, Signed2 > &rhs) noexcept
constexpr wide_integer< Bits, Signed > & operator*=(const Arithmetic &rhs)
uint32_t base_type
Definition: WideInt.h:72
constexpr wide_integer< Bits, Signed > & operator|=(const Integral &rhs) noexcept
wide_integer()=default
constexpr wide_integer< Bits, Signed > & operator=(const wide_integer< Bits2, Signed2 > &rhs) noexcept
constexpr wide_integer(T rhs) noexcept
typename std::enable_if< std::is_arithmetic< T >::value, T >::type __integral_not_wide_integer_class
Definition: WideInt.h:120
constexpr wide_integer< Bits, Signed > & operator+=(const Arithmetic &rhs) noexcept(is_same< Signed, unsigned >::value)
base_type * ptr()
Definition: WideInt.h:130
constexpr wide_integer< Bits, Signed > & operator=(Arithmetic rhs) noexcept
constexpr wide_integer< Bits, Signed > & operator-=(const Arithmetic &rhs) noexcept(is_same< Signed, unsigned >::value)
constexpr wide_integer< Bits, Signed > & operator%=(const Integral &rhs)
constexpr wide_integer< Bits, Signed > & operator^=(const Integral &rhs) noexcept
constexpr wide_integer< Bits, Signed > & operator/=(const Arithmetic &rhs)
STL namespace.
typename std::enable_if< IntegralConcept< T >() &&IntegralConcept< T2 >()>::type __only_integer
Definition: WideInt.h:147
typename std::enable_if< ArithmeticConcept< T1 >() &&ArithmeticConcept< T2 >()>::type __only_arithmetic
Definition: WideInt.h:143
static constexpr bool ArithmeticConcept() noexcept
static constexpr bool IntegralConcept() noexcept
from_chars_result from_chars(const char *first, const char *last, wide_integer< Bits, Signed > &value, int base=10)
std::wstring to_wstring(const wide_integer< Bits, Signed > &n)
to_chars_result to_chars(char *first, char *last, const wide_integer< Bits, Signed > &value, int base=10)
std::string to_string(const wide_integer< Bits, Signed > &n)
const char * ptr
Definition: WideInt.h:270
std::error_code ec
Definition: WideInt.h:271
std::error_code ec
Definition: WideInt.h:266