cpp-common/bt2c/fmt.hpp: use `wise_enum::string_type` in `EnableIfIsWiseEnum` definition
[babeltrace.git] / src / cpp-common / bt2c / data-len.hpp
1 /*
2 * Copyright (c) 2022 Philippe Proulx <pproulx@efficios.com>
3 *
4 * SPDX-License-Identifier: MIT
5 */
6
7 #ifndef BABELTRACE_CPP_COMMON_BT2C_DATA_LEN_HPP
8 #define BABELTRACE_CPP_COMMON_BT2C_DATA_LEN_HPP
9
10 #include "safe-ops.hpp"
11
12 namespace bt2c {
13
14 /*
15 * A data length is a quantity of binary data (bits).
16 *
17 * This class can make some code clearer and safer because its
18 * constructor is private so that you need to call DataLen::fromBits()
19 * or DataLen::fromBytes() to create an instance.
20 *
21 * With a `DataLen` instance `len`, use `*len` or `len.bits()` to get
22 * the quantity in bits and `len.bytes()` to get it in bytes (floored).
23 *
24 * You can add, subtract, and compare data lengths.
25 */
26 class DataLen final
27 {
28 private:
29 constexpr explicit DataLen(const unsigned long long lenBits) noexcept : _mLenBits {lenBits}
30 {
31 }
32
33 public:
34 /*
35 * Creates and returns a data length instance representing `lenBits`
36 * bits.
37 */
38 static constexpr DataLen fromBits(const unsigned long long lenBits) noexcept
39 {
40 return DataLen {lenBits};
41 }
42
43 /*
44 * Creates and returns a data length instance representing
45 * `lenBytes` bytes.
46 */
47 static DataLen fromBytes(const unsigned long long lenBytes) noexcept
48 {
49 return DataLen {safeMul(lenBytes, 8ULL)};
50 }
51
52 /*
53 * Number of bits of this data length.
54 */
55 constexpr unsigned long long operator*() const noexcept
56 {
57 return _mLenBits;
58 }
59
60 /*
61 * Number of bits of this data length.
62 */
63 constexpr unsigned long long bits() const noexcept
64 {
65 return _mLenBits;
66 }
67
68 /*
69 * Number of bytes (floor) of this data length.
70 */
71 constexpr unsigned long long bytes() const noexcept
72 {
73 return _mLenBits / 8;
74 }
75
76 /*
77 * Whether or not this data length represents a multiple of eight
78 * bits.
79 */
80 constexpr bool hasExtraBits() const noexcept
81 {
82 return this->extraBitCount() > 0;
83 }
84
85 /*
86 * Remainder of this data length, in bits, divided by eight.
87 */
88 constexpr unsigned int extraBitCount() const noexcept
89 {
90 return _mLenBits & 7;
91 }
92
93 /*
94 * Returns whether or not this data length is a power of two bits.
95 */
96 constexpr bool isPowOfTwo() const noexcept
97 {
98 return ((_mLenBits & (_mLenBits - 1)) == 0) && _mLenBits > 0;
99 }
100
101 constexpr bool operator==(const DataLen& other) const noexcept
102 {
103 return _mLenBits == other._mLenBits;
104 }
105
106 constexpr bool operator!=(const DataLen& other) const noexcept
107 {
108 return !(*this == other);
109 }
110
111 constexpr bool operator<(const DataLen& other) const noexcept
112 {
113 return _mLenBits < other._mLenBits;
114 }
115
116 constexpr bool operator<=(const DataLen& other) const noexcept
117 {
118 return (*this == other) || (*this < other);
119 }
120
121 constexpr bool operator>(const DataLen& other) const noexcept
122 {
123 return !(*this <= other);
124 }
125
126 constexpr bool operator>=(const DataLen& other) const noexcept
127 {
128 return (*this > other) || (*this == other);
129 }
130
131 DataLen& operator+=(const DataLen len) noexcept
132 {
133 _mLenBits = safeAdd(_mLenBits, len._mLenBits);
134 return *this;
135 }
136
137 DataLen& operator-=(const DataLen len) noexcept
138 {
139 _mLenBits = safeSub(_mLenBits, len._mLenBits);
140 return *this;
141 }
142
143 DataLen& operator*=(const unsigned long long mul) noexcept
144 {
145 _mLenBits = safeMul(_mLenBits, mul);
146 return *this;
147 }
148
149 private:
150 unsigned long long _mLenBits = 0;
151 };
152
153 static inline DataLen operator+(const DataLen lenA, const DataLen lenB) noexcept
154 {
155 return DataLen::fromBits(safeAdd(*lenA, *lenB));
156 }
157
158 static inline DataLen operator-(const DataLen lenA, const DataLen lenB) noexcept
159 {
160 return DataLen::fromBits(safeSub(*lenA, *lenB));
161 }
162
163 static inline DataLen operator*(const DataLen len, const unsigned long long mul) noexcept
164 {
165 return DataLen::fromBits(safeMul(*len, mul));
166 }
167
168 /*
169 * Use this namespace to access handy data length user literals, for
170 * example:
171 *
172 * using namespace bt2c::literals::datalen;
173 *
174 * const auto bufSize = 64_MiBytes + 8_KiBits;
175 */
176 namespace literals {
177 namespace datalen {
178
179 static inline DataLen operator""_bits(const unsigned long long val) noexcept
180 {
181 return DataLen::fromBits(val);
182 }
183
184 static inline DataLen operator""_KiBits(const unsigned long long val) noexcept
185 {
186 return DataLen::fromBits(safeMul(val, 1024ULL));
187 }
188
189 static inline DataLen operator""_MiBits(const unsigned long long val) noexcept
190 {
191 return DataLen::fromBits(safeMul(val, 1024ULL * 1024));
192 }
193
194 static inline DataLen operator""_GiBits(const unsigned long long val) noexcept
195 {
196 return DataLen::fromBits(safeMul(val, 1024ULL * 1024 * 1024));
197 }
198
199 static inline DataLen operator""_bytes(const unsigned long long val) noexcept
200 {
201 return DataLen::fromBytes(val);
202 }
203
204 static inline DataLen operator""_KiBytes(const unsigned long long val) noexcept
205 {
206 return DataLen::fromBytes(safeMul(val, 1024ULL));
207 }
208
209 static inline DataLen operator""_MiBytes(const unsigned long long val) noexcept
210 {
211 return DataLen::fromBytes(safeMul(val, 1024ULL * 1024));
212 }
213
214 static inline DataLen operator""_GiBytes(const unsigned long long val) noexcept
215 {
216 return DataLen::fromBytes(safeMul(val, 1024ULL * 1024 * 1024));
217 }
218
219 } /* namespace datalen */
220 } /* namespace literals */
221 } /* namespace bt2c */
222
223 #endif /* BABELTRACE_CPP_COMMON_BT2C_DATA_LEN_HPP */
This page took 0.032847 seconds and 4 git commands to generate.