11#ifndef GUDHI_UINT128_H_
12#define GUDHI_UINT128_H_
13#include <gudhi/Debug_utils.h>
16#include <boost/container_hash/hash.hpp>
29#if !defined __SIZEOF_INT128__ || defined GUDHI_FORCE_FAKE_UINT128
30namespace Gudhi::numbers {
33 #ifdef __SIZEOF_INT128__
34 unsigned __int128 native()
const {
return ((
unsigned __int128)high << 64) + low; }
35 #define GUDHI_VERIF(X) GUDHI_CHECK(res.native() == (X), "")
37 #define GUDHI_VERIF(X)
40 constexpr Fake_uint128(): high(0), low(0) {}
41 constexpr Fake_uint128(std::uint64_t a): high(0), low(a) {}
44 friend Fake_uint128 operator+(Fake_uint128 a, Fake_uint128 b){
46 res.low = a.low + b.low;
47 res.high = a.high + b.high + (res.low < a.low);
48 GUDHI_VERIF (a.native() + b.native());
51 friend Fake_uint128 operator-(Fake_uint128 a, Fake_uint128 b){
53 res.low = a.low - b.low;
54 res.high = a.high - b.high - (res.low > a.low);
55 GUDHI_VERIF (a.native() - b.native());
58 friend Fake_uint128
operator<<(Fake_uint128 a, uint8_t b){
60 GUDHI_CHECK(b < 128,
"");
61 if (b >= 64) { res.low = 0; res.high = a.low << (b-64); }
62 else if (b == 0) { res = a; }
63 else { res.low = a.low << b; res.high = a.high << b | a.low >> (64-b); }
64 GUDHI_VERIF (a.native() << b);
67 friend Fake_uint128 operator>>(Fake_uint128 a, uint8_t b){
69 GUDHI_CHECK(b < 128,
"");
70 if (b >= 64) { res.high = 0; res.low = a.high >> (b-64); }
71 else if (b == 0) { res = a; }
72 else { res.high = a.high >> b; res.low = a.low >> b | a.high << (64-b); }
73 GUDHI_VERIF (a.native() >> b);
76 friend Fake_uint128 operator&(Fake_uint128 a, Fake_uint128 b){
78 res.low = a.low & b.low;
79 res.high = a.high & b.high;
80 GUDHI_VERIF (a.native() & b.native());
83 friend Fake_uint128 operator|(Fake_uint128 a, Fake_uint128 b){
85 res.low = a.low | b.low;
86 res.high = a.high | b.high;
87 GUDHI_VERIF (a.native() | b.native());
90 friend Fake_uint128 operator~(Fake_uint128 a){
97 Fake_uint128& operator+=(Fake_uint128 a) { *
this = *
this + a;
return *
this; }
98 Fake_uint128& operator-=(Fake_uint128 a) { *
this = *
this - a;
return *
this; }
99 Fake_uint128& operator++() {
if (++low == 0) ++high;
return *
this; }
100 Fake_uint128& operator--() {
if (low-- == 0) --high;
return *
this; }
101 Fake_uint128& operator<<=(uint8_t a) { *
this = *
this << a;
return *
this; }
102 Fake_uint128& operator>>=(uint8_t a) { *
this = *
this >> a;
return *
this; }
103 Fake_uint128& operator&=(Fake_uint128 a) { *
this = *
this & a;
return *
this; }
104 Fake_uint128& operator|=(Fake_uint128 a) { *
this = *
this | a;
return *
this; }
106 friend bool operator==(Fake_uint128 a, Fake_uint128 b){
107 return a.low == b.low && a.high == b.high;
109 friend bool operator!=(Fake_uint128 a, Fake_uint128 b){
110 return a.low != b.low || a.high != b.high;
112 friend bool operator<(Fake_uint128 a, Fake_uint128 b){
113 return a.high < b.high || (a.high == b.high && a.low < b.low);
115 friend bool operator>(Fake_uint128 a, Fake_uint128 b){
116 return a.high > b.high || (a.high == b.high && a.low > b.low);
118 friend bool operator<=(Fake_uint128 a, Fake_uint128 b){
119 return a.high < b.high || (a.high == b.high && a.low <= b.low);
121 friend bool operator>=(Fake_uint128 a, Fake_uint128 b){
122 return a.high > b.high || (a.high == b.high && a.low >= b.low);
125 friend std::size_t hash_value(Fake_uint128 a) {
126 typedef std::pair<std::uint64_t, std::uint64_t> P;
127 return boost::hash_value(P(a.high, a.low));
129 template <
class T,
class=std::enable_if_t<std::is_
integral_v<T>>>
130 explicit operator T()
const {
131 GUDHI_CHECK(high == 0 && low <= std::numeric_limits<T>::max(),
"");
132 return static_cast<T
>(low);
135 std::uint64_t high, low;
138typedef Fake_uint128 uint128_t;
140template<>
class std::numeric_limits<
Gudhi::numbers::Fake_uint128> {
142 static constexpr bool is_specialized =
true;
143 static constexpr bool is_signed =
false;
144 static constexpr bool is_integer =
true;
145 static constexpr bool is_exact =
true;
146 static constexpr bool has_infinity =
false;
147 static constexpr bool is_modulo =
true;
148 static constexpr int digits = 128;
149 static constexpr int radix = 2;
153namespace Gudhi::numbers {
154typedef unsigned __int128 uint128_t;
std::ostream & operator<<(std::ostream &os, const Permutahedral_representation< Vertex, OrderedSetPartition > &simplex)
Print a permutahedral representation to a stream.
Definition: Permutahedral_representation.h:173
Gudhi namespace.
Definition: SimplicialComplexForAlpha.h:14