tudocomp
– The TU Dortmund Compression Framework
uint_t.hpp
Go to the documentation of this file.
1 #pragma once
2 
4 
5 #include <cstdint>
6 #include <cmath>
7 
8 namespace tdc {
9 
10 template<size_t bits>
12 
13 template<class MB>
14 struct UinttDispatch {
15  typedef MB SelfMaxBit;
16 
17  template<class Ref, class V>
18  inline static void assign(Ref& self, V v) {
19  self.m_data = v;
20  }
21 
22  template<class Ref, class R>
23  inline static R cast_for_op(const Ref& self) {
24  return self.m_data;
25  }
26 };
27 
28 template<size_t N>
29 struct ConstIntegerBaseTrait<uint_impl_t<N>, typename std::enable_if<(N <= 32)>::type> {
30  typedef UinttDispatch<uint32_t> Dispatch;
31 };
32 
33 template<size_t N>
34 struct IntegerBaseTrait<uint_impl_t<N>, typename std::enable_if<(N <= 32)>::type>
35 : ConstIntegerBaseTrait<uint_impl_t<N>> {
37 };
38 
39 template<size_t N>
40 struct ConstIntegerBaseTrait<uint_impl_t<N>, typename std::enable_if<(N > 32)>::type> {
42 };
43 
44 template<size_t N>
45 struct IntegerBaseTrait<uint_impl_t<N>, typename std::enable_if<(N > 32)>::type>
46 : ConstIntegerBaseTrait<uint_impl_t<N>> {
47  typedef UinttDispatch<uint64_t> Dispatch;
48 };
49 
50 template<>
51 struct ConstIntegerBaseTrait<bool> {
52  typedef UinttDispatch<uint32_t> Dispatch;
53 };
54 
55 template<>
56 struct IntegerBaseTrait<bool>
57 : ConstIntegerBaseTrait<bool> {
59 };
60 
70 template<size_t bits>
71 class uint_impl_t: public IntegerBase<uint_impl_t<bits>> {
72  static_assert(bits > 0, "bits must be non-negative");
73  static_assert(bits < 65, "bits must be at most 64");
74  uint64_t m_data: bits;
75 
76  friend struct UinttDispatch<uint32_t>;
77  friend struct UinttDispatch<uint64_t>;
78 
79 public:
80  constexpr uint_impl_t(): m_data(0) {}
81  constexpr uint_impl_t(uint_impl_t&& i): m_data(i.m_data) {}
82 
83  // copying
84  constexpr uint_impl_t(const uint_impl_t& i): m_data(i.m_data) {}
85  inline uint_impl_t& operator=(const uint_impl_t& b) { m_data = b.m_data; return *this; }
86 
87  // conversions for all fundamental char types
88  constexpr uint_impl_t(unsigned char i): m_data(i) {}
89  inline uint_impl_t& operator=(unsigned char data) { m_data = data; return *this; }
90  constexpr operator unsigned char() const { return m_data; }
91 
92  constexpr uint_impl_t(signed char i): m_data(i) {}
93  inline uint_impl_t& operator=(signed char data) { m_data = data; return *this; }
94  constexpr operator signed char() const { return m_data; }
95 
96  constexpr uint_impl_t(char i): m_data(i) {}
97  constexpr uint_impl_t& operator=(char data) { m_data = data; return *this; }
98  constexpr operator char() const { return m_data; }
99 
100  // conversions for all fundamental integer types
101  constexpr uint_impl_t(unsigned int i): m_data(i) {}
102  inline uint_impl_t& operator=(unsigned int data) { m_data = data; return *this; }
103  constexpr operator unsigned int() const { return m_data; }
104 
105  constexpr uint_impl_t(unsigned short int i): m_data(i) {}
106  inline uint_impl_t& operator=(unsigned short int data) { m_data = data; return *this; }
107  constexpr operator unsigned short int() const { return m_data; }
108 
109  constexpr uint_impl_t(unsigned long int i): m_data(i) {}
110  inline uint_impl_t& operator=(unsigned long int data) { m_data = data; return *this; }
111  constexpr operator unsigned long int() const { return m_data; }
112 
113  constexpr uint_impl_t(unsigned long long int i): m_data(i) {}
114  inline uint_impl_t& operator=(unsigned long long int data) { m_data = data; return *this; }
115  constexpr operator unsigned long long int() const { return m_data; }
116 
117  constexpr uint_impl_t(int i): m_data(i) {}
118  inline uint_impl_t& operator=(int data) { m_data = data; return *this; }
119  constexpr operator int() const { return m_data; }
120 
121  constexpr uint_impl_t(short int i): m_data(i) {}
122  inline uint_impl_t& operator=(short int data) { m_data = data; return *this; }
123  constexpr operator short int() const { return m_data; }
124 
125  constexpr uint_impl_t(long int i): m_data(i) {}
126  inline uint_impl_t& operator=(long int data) { m_data = data; return *this; }
127  constexpr operator long int() const { return m_data; }
128 
129  constexpr uint_impl_t(long long int i): m_data(i) {}
130  inline uint_impl_t& operator=(long long int data) { m_data = data; return *this; }
131  constexpr operator long long int() const { return m_data; }
132 } __attribute__((packed));
133 
134 template<size_t N>
135 inline std::ostream& operator<<(std::ostream& os, const uint_impl_t<N>& v) {
136  return os << uint64_t(v);
137 }
138 
139 template<size_t N>
140 inline std::istream& operator>>(std::istream& is, uint_impl_t<N>& v) {
141  uint64_t v2;
142  auto& x = is >> v2;
143  v = v2;
144  return x;
145 }
146 
147 // Specialize uint_t<1> to be identical to bool
148 
149 // We disable 1-Bit instantiation of the actual type because the typedef
150 // below will redirect uint_t<1> to bool.
151 template<>
152 class uint_impl_t<1> {};
153 
154 template<size_t N>
157 };
158 
159 template<>
160 struct uint_dispatch_t<1> {
161  using type = bool;
162 };
163 
164 template<size_t N>
166 
167 static_assert(sizeof(uint_t<8>) == 1, "sanity check");
168 static_assert(sizeof(uint_t<16>) == 2, "sanity check");
169 static_assert(sizeof(uint_t<24>) == 3, "sanity check");
170 static_assert(sizeof(uint_t<32>) == 4, "sanity check");
171 static_assert(sizeof(uint_t<40>) == 5, "sanity check");
172 static_assert(sizeof(uint_t<48>) == 6, "sanity check");
173 static_assert(sizeof(uint_t<56>) == 7, "sanity check");
174 static_assert(sizeof(uint_t<64>) == 8, "sanity check");
175 
176 static_assert(sizeof(uint_t<7>) == 1, "sanity check");
177 static_assert(sizeof(uint_t<15>) == 2, "sanity check");
178 static_assert(sizeof(uint_t<23>) == 3, "sanity check");
179 static_assert(sizeof(uint_t<31>) == 4, "sanity check");
180 static_assert(sizeof(uint_t<39>) == 5, "sanity check");
181 static_assert(sizeof(uint_t<47>) == 6, "sanity check");
182 static_assert(sizeof(uint_t<55>) == 7, "sanity check");
183 static_assert(sizeof(uint_t<63>) == 8, "sanity check");
184 
185 static_assert(sizeof(uint_t<9>) == 2, "sanity check");
186 static_assert(sizeof(uint_t<17>) == 3, "sanity check");
187 static_assert(sizeof(uint_t<25>) == 4, "sanity check");
188 static_assert(sizeof(uint_t<33>) == 5, "sanity check");
189 static_assert(sizeof(uint_t<41>) == 6, "sanity check");
190 static_assert(sizeof(uint_t<49>) == 7, "sanity check");
191 static_assert(sizeof(uint_t<57>) == 8, "sanity check");
192 
193 }
194 
195 namespace std {
196  template<size_t N>
197  class numeric_limits<tdc::uint_impl_t<N>> {
198  using T = tdc::uint_impl_t<N>;
199  public:
200  static constexpr bool is_specialized = true;
201  static constexpr bool is_signed = false;
202  static constexpr bool is_integer = true;
203  static constexpr bool is_exact = true;
204  static constexpr bool has_infinity = false;
205  static constexpr bool has_quiet_NaN = false;
206  static constexpr bool has_signaling_NaN = false;
207  static constexpr std::float_denorm_style has_denorm = std::denorm_absent;
208  static constexpr bool has_denorm_loss = false;
209  static constexpr std::float_round_style round_style = std::round_toward_zero;
210  static constexpr bool is_iec559 = false;
211  static constexpr bool is_bounded = true;
212 
213  // TODO: Not true currently, would need code to support it
214  static constexpr bool is_modulo = false;
215 
216  static constexpr int digits = N;
217  static constexpr int digits10 = std::numeric_limits<T>::digits * std::log10(2);
218  static constexpr int max_digits10 = 0;
219  static constexpr int radix = 2;
220  static constexpr int min_exponent = 0;
221  static constexpr int min_exponent10 = 0;
222  static constexpr int max_exponent = 0;
223  static constexpr int max_exponent10 = 0;
224 
225  // Maybe need to derive from base uint64_t type
226  static constexpr bool traps = true;
227  static constexpr bool tinyness_before = false;
228 
229  static constexpr T min() { return 0; }
230  static constexpr T lowest() { return 0; }
231  static constexpr T max() { return uint64_t(std::pow(2, N) - 1); }
232  static constexpr T epsilon() { return 0; }
233  static constexpr T round_error() { return 0; }
234  static constexpr T infinity() { return 0; }
235  static constexpr T quiet_NaN() { return 0; }
236  static constexpr T signaling_NaN() { return 0; }
237  static constexpr T denorm_min() { return 0; }
238  };
239 
240  template<size_t N>
241  std::string to_string(tdc::uint_impl_t<N> value) {
242  return std::to_string(uint64_t(value));
243  }
244 
245  template<size_t N>
246  struct hash<tdc::uint_impl_t<N>> {
247  size_t operator()(const tdc::uint_impl_t<N>& x) const {
248  return hash<uint64_t>()(x);
249  }
250  };
251 }
uint_impl_t & operator=(long long int data)
Definition: uint_t.hpp:130
Contains the text compression and encoding framework.
Definition: namespaces.hpp:11
uint_impl_t & operator=(const uint_impl_t &b)
Definition: uint_t.hpp:43
IntegerBaseCombiner< IntegerBaseWithSelf< Self >, IntegerBaseWith32< Self, unsigned char >, IntegerBaseWith32< Self, char >, IntegerBaseWith32< Self, signed char >, IntegerBaseWith32< Self, unsigned short int >, IntegerBaseWith32< Self, signed short int >, IntegerBaseWith32< Self, unsigned int >, IntegerBaseWith32< Self, signed int >, IntegerBaseWith64< Self, unsigned long int >, IntegerBaseWith64< Self, signed long int >, IntegerBaseWith64< Self, unsigned long long int >, IntegerBaseWith64< Self, signed long long int > > IntegerBase
constexpr uint_impl_t(int i)
Definition: uint_t.hpp:117
static R cast_for_op(const Ref &self)
Definition: uint_t.hpp:23
UinttDispatch< uint32_t > Dispatch
Definition: uint_t.hpp:36
uint_impl_t & operator=(signed char data)
Definition: uint_t.hpp:93
static void assign(Ref &self, V v)
Definition: uint_t.hpp:18
uint_impl_t & operator=(long int data)
Definition: uint_t.hpp:126
std::string to_string(tdc::uint_impl_t< N > value)
Definition: uint_t.hpp:241
constexpr uint_impl_t(unsigned long long int i)
Definition: uint_t.hpp:113
constexpr uint_impl_t(long int i)
Definition: uint_t.hpp:125
uint_impl_t & operator=(unsigned long long int data)
Definition: uint_t.hpp:114
constexpr uint_impl_t(unsigned int i)
Definition: uint_t.hpp:101
uint_impl_t & operator=(unsigned int data)
Definition: uint_t.hpp:102
uint_impl_t & operator=(int data)
Definition: uint_t.hpp:118
constexpr uint_impl_t(short int i)
Definition: uint_t.hpp:121
std::istream & operator>>(std::istream &is, uint_impl_t< N > &v)
Definition: uint_t.hpp:140
constexpr uint_impl_t & operator=(char data)
Definition: uint_t.hpp:97
typename uint_dispatch_t< N >::type uint_t
Definition: uint_t.hpp:165
uint_impl_t & operator=(short int data)
Definition: uint_t.hpp:122
UinttDispatch< uint64_t > Dispatch
Definition: uint_t.hpp:41
friend struct UinttDispatch< uint32_t >
Definition: uint_t.hpp:34
UinttDispatch< uint32_t > Dispatch
Definition: uint_t.hpp:58
constexpr uint_impl_t(unsigned short int i)
Definition: uint_t.hpp:105
uint64_t m_data
Definition: uint_t.hpp:30
friend struct UinttDispatch< uint64_t >
Definition: uint_t.hpp:35
uint_impl_t & operator=(unsigned long int data)
Definition: uint_t.hpp:110
constexpr uint_impl_t(unsigned long int i)
Definition: uint_t.hpp:109
Custom integer type for storing values of arbitrary bit size bits.
Definition: uint_t.hpp:11
uint_impl_t & operator=(unsigned short int data)
Definition: uint_t.hpp:106
class tdc::uint_impl_t< 1 > __attribute__
size_t operator()(const tdc::uint_impl_t< N > &x) const
Definition: uint_t.hpp:247
constexpr uint_impl_t()
Definition: uint_t.hpp:38
constexpr uint_impl_t(signed char i)
Definition: uint_t.hpp:92
constexpr uint_impl_t(char i)
Definition: uint_t.hpp:96
constexpr uint_impl_t(long long int i)
Definition: uint_t.hpp:129