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 <random>
32#include <sstream>
33#include <stdexcept>
34#include <stdint.h>
35#include <system_error>
36#include <type_traits>
37
61namespace std {
62template <size_t Bits, typename Signed> class wide_integer;
63
64template <size_t Bits, typename Signed, size_t Bits2, typename Signed2>
65struct common_type<wide_integer<Bits, Signed>, wide_integer<Bits2, Signed2>>;
66
67template <size_t Bits, typename Signed, typename Arithmetic> struct common_type<wide_integer<Bits, Signed>, Arithmetic>;
68
69template <typename Arithmetic, size_t Bits, typename Signed> struct common_type<Arithmetic, wide_integer<Bits, Signed>>;
70
71template <size_t Bits, typename Signed> class wide_integer {
72public:
73 using base_type = uint32_t;
74 using signed_base_type = int32_t;
75
76 // ctors
77 wide_integer() = default;
78
79 template <typename T> constexpr wide_integer(T rhs) noexcept;
80 template <size_t Bits2, typename Signed2> constexpr wide_integer(const wide_integer<Bits2, Signed2> &rhs) noexcept;
81
82 // assignment
83 template <size_t Bits2, typename Signed2>
85
86 template <typename Arithmetic> constexpr wide_integer<Bits, Signed> &operator=(Arithmetic rhs) noexcept;
87
88 template <typename Arithmetic> constexpr wide_integer<Bits, Signed> &operator*=(const Arithmetic &rhs);
89
90 template <typename Arithmetic> constexpr wide_integer<Bits, Signed> &operator/=(const Arithmetic &rhs);
91
92 template <typename Arithmetic>
93 constexpr wide_integer<Bits, Signed> &operator+=(const Arithmetic &rhs) noexcept(is_same<Signed, unsigned>::value);
94
95 template <typename Arithmetic>
96 constexpr wide_integer<Bits, Signed> &operator-=(const Arithmetic &rhs) noexcept(is_same<Signed, unsigned>::value);
97
98 template <typename Integral> constexpr wide_integer<Bits, Signed> &operator%=(const Integral &rhs);
99
100 template <typename Integral> constexpr wide_integer<Bits, Signed> &operator&=(const Integral &rhs) noexcept;
101
102 template <typename Integral> constexpr wide_integer<Bits, Signed> &operator|=(const Integral &rhs) noexcept;
103
104 template <typename Integral> constexpr wide_integer<Bits, Signed> &operator^=(const Integral &rhs) noexcept;
105
106 template <typename T2, typename = std::enable_if<std::is_integral<T2>::value && std::is_unsigned<T2>::value>>
107 constexpr wide_integer<Bits, Signed> &operator<<=(T2 n) noexcept;
108 template <typename T2, typename = std::enable_if<std::is_integral<T2>::value && std::is_unsigned<T2>::value>>
109 constexpr wide_integer<Bits, Signed> &operator>>=(T2 n) noexcept;
110
111 constexpr wide_integer<Bits, Signed> &operator++() noexcept(is_same<Signed, unsigned>::value);
112 constexpr wide_integer<Bits, Signed> operator++(int) noexcept(is_same<Signed, unsigned>::value);
113 constexpr wide_integer<Bits, Signed> &operator--() noexcept(is_same<Signed, unsigned>::value);
114 constexpr wide_integer<Bits, Signed> operator--(int) noexcept(is_same<Signed, unsigned>::value);
115
116 // observers
117
118 constexpr explicit operator bool() const noexcept;
119
120 template <class T>
121 using __integral_not_wide_integer_class = typename std::enable_if<std::is_arithmetic<T>::value, T>::type;
122
123 template <class T, class = __integral_not_wide_integer_class<T>> constexpr operator T() const noexcept;
124
125 constexpr operator long double() const noexcept;
126 constexpr operator double() const noexcept;
127 constexpr operator float() const noexcept;
128
129 struct _impl;
130 const base_type *ptr() const { return m_arr; }
131 base_type *ptr() { return m_arr; }
132
133private:
134 template <size_t Bits2, typename Signed2> friend class wide_integer;
135
136 friend class numeric_limits<wide_integer<Bits, signed>>;
137 friend class numeric_limits<wide_integer<Bits, unsigned>>;
138
139 base_type m_arr[_impl::arr_size];
140};
141
142template <typename T> static constexpr bool ArithmeticConcept() noexcept;
143template <class T1, class T2>
144using __only_arithmetic = typename std::enable_if<ArithmeticConcept<T1>() && ArithmeticConcept<T2>()>::type;
145
146template <typename T> static constexpr bool IntegralConcept() noexcept;
147template <class T, class T2>
148using __only_integer = typename std::enable_if<IntegralConcept<T>() && IntegralConcept<T2>()>::type;
149
150// Unary operators
151template <size_t Bits, typename Signed>
152constexpr wide_integer<Bits, Signed> operator~(const wide_integer<Bits, Signed> &lhs) noexcept;
153
154template <size_t Bits, typename Signed>
155constexpr wide_integer<Bits, Signed>
156operator-(const wide_integer<Bits, Signed> &lhs) noexcept(is_same<Signed, unsigned>::value);
157
158template <size_t Bits, typename Signed>
159constexpr wide_integer<Bits, Signed>
160operator+(const wide_integer<Bits, Signed> &lhs) noexcept(is_same<Signed, unsigned>::value);
161
162// Binary operators
163template <size_t Bits, typename Signed, size_t Bits2, typename Signed2>
164std::common_type_t<wide_integer<Bits, Signed>, wide_integer<Bits2, Signed2>> constexpr
165operator*(const wide_integer<Bits, Signed> &lhs, const wide_integer<Bits2, Signed2> &rhs);
166template <typename Arithmetic, typename Arithmetic2, class = __only_arithmetic<Arithmetic, Arithmetic2>>
167std::common_type_t<Arithmetic, Arithmetic2> constexpr operator*(const Arithmetic &rhs, const Arithmetic2 &lhs);
168
169template <size_t Bits, typename Signed, size_t Bits2, typename Signed2>
170std::common_type_t<wide_integer<Bits, Signed>, wide_integer<Bits2, Signed2>> constexpr
171operator/(const wide_integer<Bits, Signed> &lhs, const wide_integer<Bits2, Signed2> &rhs);
172template <typename Arithmetic, typename Arithmetic2, class = __only_arithmetic<Arithmetic, Arithmetic2>>
173std::common_type_t<Arithmetic, Arithmetic2> constexpr operator/(const Arithmetic &rhs, const Arithmetic2 &lhs);
174
175template <size_t Bits, typename Signed, size_t Bits2, typename Signed2>
176std::common_type_t<wide_integer<Bits, Signed>, wide_integer<Bits2, Signed2>> constexpr
177operator+(const wide_integer<Bits, Signed> &lhs, const wide_integer<Bits2, Signed2> &rhs);
178template <typename Arithmetic, typename Arithmetic2, class = __only_arithmetic<Arithmetic, Arithmetic2>>
179std::common_type_t<Arithmetic, Arithmetic2> constexpr operator+(const Arithmetic &rhs, const Arithmetic2 &lhs);
180
181template <size_t Bits, typename Signed, size_t Bits2, typename Signed2>
182std::common_type_t<wide_integer<Bits, Signed>, wide_integer<Bits2, Signed2>> constexpr
183operator-(const wide_integer<Bits, Signed> &lhs, const wide_integer<Bits2, Signed2> &rhs);
184template <typename Arithmetic, typename Arithmetic2, class = __only_arithmetic<Arithmetic, Arithmetic2>>
185std::common_type_t<Arithmetic, Arithmetic2> constexpr operator-(const Arithmetic &rhs, const Arithmetic2 &lhs);
186
187template <size_t Bits, typename Signed, size_t Bits2, typename Signed2>
188std::common_type_t<wide_integer<Bits, Signed>, wide_integer<Bits2, Signed2>> constexpr
189operator%(const wide_integer<Bits, Signed> &lhs, const wide_integer<Bits2, Signed2> &rhs);
190template <typename Integral, typename Integral2, class = __only_integer<Integral, Integral2>>
191std::common_type_t<Integral, Integral2> constexpr operator%(const Integral &rhs, const Integral2 &lhs);
192
193template <size_t Bits, typename Signed, size_t Bits2, typename Signed2>
194std::common_type_t<wide_integer<Bits, Signed>, wide_integer<Bits2, Signed2>> constexpr
195operator&(const wide_integer<Bits, Signed> &lhs, const wide_integer<Bits2, Signed2> &rhs);
196template <typename Integral, typename Integral2, class = __only_integer<Integral, Integral2>>
197std::common_type_t<Integral, Integral2> constexpr operator&(const Integral &rhs, const Integral2 &lhs);
198
199template <size_t Bits, typename Signed, size_t Bits2, typename Signed2>
200std::common_type_t<wide_integer<Bits, Signed>, wide_integer<Bits2, Signed2>> constexpr
201operator|(const wide_integer<Bits, Signed> &lhs, const wide_integer<Bits2, Signed2> &rhs);
202template <typename Integral, typename Integral2, class = __only_integer<Integral, Integral2>>
203std::common_type_t<Integral, Integral2> constexpr operator|(const Integral &rhs, const Integral2 &lhs);
204
205template <size_t Bits, typename Signed, size_t Bits2, typename Signed2>
206std::common_type_t<wide_integer<Bits, Signed>, wide_integer<Bits2, Signed2>> constexpr
207operator^(const wide_integer<Bits, Signed> &lhs, const wide_integer<Bits2, Signed2> &rhs);
208template <typename Integral, typename Integral2, class = __only_integer<Integral, Integral2>>
209std::common_type_t<Integral, Integral2> constexpr operator^(const Integral &rhs, const Integral2 &lhs);
210
211// TODO: Integral
212template <size_t Bits, typename Signed, typename T2,
213 typename = std::enable_if<std::is_integral<T2>::value && std::is_unsigned<T2>::value>>
214constexpr wide_integer<Bits, Signed> operator<<(const wide_integer<Bits, Signed> &lhs, T2 n) noexcept;
215
216template <size_t Bits, typename Signed, typename T2,
217 typename = std::enable_if<std::is_integral<T2>::value && std::is_unsigned<T2>::value>>
218constexpr wide_integer<Bits, Signed> operator>>(const wide_integer<Bits, Signed> &lhs, T2 n) noexcept;
219
220template <size_t Bits, typename Signed, size_t Bits2, typename Signed2>
221constexpr bool operator<(const wide_integer<Bits, Signed> &lhs, const wide_integer<Bits2, Signed2> &rhs);
222template <typename Arithmetic, typename Arithmetic2, class = __only_arithmetic<Arithmetic, Arithmetic2>>
223constexpr bool operator<(const Arithmetic &rhs, const Arithmetic2 &lhs);
224
225template <size_t Bits, typename Signed, size_t Bits2, typename Signed2>
226constexpr bool operator>(const wide_integer<Bits, Signed> &lhs, const wide_integer<Bits2, Signed2> &rhs);
227template <typename Arithmetic, typename Arithmetic2, class = __only_arithmetic<Arithmetic, Arithmetic2>>
228constexpr bool operator>(const Arithmetic &rhs, const Arithmetic2 &lhs);
229
230template <size_t Bits, typename Signed, size_t Bits2, typename Signed2>
231constexpr bool operator<=(const wide_integer<Bits, Signed> &lhs, const wide_integer<Bits2, Signed2> &rhs);
232template <typename Arithmetic, typename Arithmetic2, class = __only_arithmetic<Arithmetic, Arithmetic2>>
233constexpr bool operator<=(const Arithmetic &rhs, const Arithmetic2 &lhs);
234
235template <size_t Bits, typename Signed, size_t Bits2, typename Signed2>
236constexpr bool operator>=(const wide_integer<Bits, Signed> &lhs, const wide_integer<Bits2, Signed2> &rhs);
237template <typename Arithmetic, typename Arithmetic2, class = __only_arithmetic<Arithmetic, Arithmetic2>>
238constexpr bool operator>=(const Arithmetic &rhs, const Arithmetic2 &lhs);
239
240template <size_t Bits, typename Signed, size_t Bits2, typename Signed2>
241constexpr bool operator==(const wide_integer<Bits, Signed> &lhs, const wide_integer<Bits2, Signed2> &rhs);
242template <typename Arithmetic, typename Arithmetic2, class = __only_arithmetic<Arithmetic, Arithmetic2>>
243constexpr bool operator==(const Arithmetic &rhs, const Arithmetic2 &lhs);
244
245template <size_t Bits, typename Signed, size_t Bits2, typename Signed2>
246constexpr bool operator!=(const wide_integer<Bits, Signed> &lhs, const wide_integer<Bits2, Signed2> &rhs);
247template <typename Arithmetic, typename Arithmetic2, class = __only_arithmetic<Arithmetic, Arithmetic2>>
248constexpr bool operator!=(const Arithmetic &rhs, const Arithmetic2 &lhs);
249
250template <size_t Bits, typename Signed> std::string to_string(const wide_integer<Bits, Signed> &n);
251
252template <size_t Bits, typename Signed> std::wstring to_wstring(const wide_integer<Bits, Signed> &n);
253
254template <size_t Bits, typename Signed>
255std::ostream &operator<<(std::ostream &out, const wide_integer<Bits, Signed> &n);
256
257template <size_t Bits, typename Signed>
258std::wostream &operator<<(std::wostream &out, const wide_integer<Bits, Signed> &n);
259
260template <size_t Bits, typename Signed> std::istream &operator>>(std::istream &in, wide_integer<Bits, Signed> &n);
261
262template <size_t Bits, typename Signed> std::wistream &operator>>(std::wistream &in, wide_integer<Bits, Signed> &n);
263
264inline namespace literals {
265inline namespace wide_integer_literals {
266template <size_t Bits> using wide_int = wide_integer<Bits, signed>;
267
268template <size_t Bits> using wide_uint = wide_integer<Bits, unsigned>;
269
272
275
278
279} // namespace wide_integer_literals
280} // namespace literals
281
282constexpr int128_t operator"" _cppi128(const char *n);
283constexpr int256_t operator"" _cppi256(const char *n);
284constexpr int512_t operator"" _cppi512(const char *n);
285constexpr uint128_t operator"" _cppui128(const char *n);
286constexpr uint256_t operator"" _cppui256(const char *n);
287constexpr uint512_t operator"" _cppui512(const char *n);
288
289// numeric limits
290template <size_t Bits, typename Signed> class numeric_limits<wide_integer<Bits, Signed>>;
291
292template <size_t Bits, typename Signed> struct hash<wide_integer<Bits, Signed>>;
293
294} // namespace std
295
296#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:130
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:139
int32_t signed_base_type
Definition WideInt.h:74
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:73
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:121
constexpr wide_integer< Bits, Signed > & operator+=(const Arithmetic &rhs) noexcept(is_same< Signed, unsigned >::value)
base_type * ptr()
Definition WideInt.h:131
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)
wide_integer< Bits, signed > wide_int
Definition WideInt.h:266
wide_integer< Bits, unsigned > wide_uint
Definition WideInt.h:268
STL namespace.
typename std::enable_if< IntegralConcept< T >() &&IntegralConcept< T2 >()>::type __only_integer
Definition WideInt.h:148
typename std::enable_if< ArithmeticConcept< T1 >() &&ArithmeticConcept< T2 >()>::type __only_arithmetic
Definition WideInt.h:144
static constexpr bool ArithmeticConcept() noexcept
static constexpr bool IntegralConcept() noexcept
std::wstring to_wstring(const wide_integer< Bits, Signed > &n)
std::string to_string(const wide_integer< Bits, Signed > &n)