cpp-common/bt2c: add `DataLen` class (general-purpose data length)
[babeltrace.git] / src / cpp-common / bt2c / data-len.hpp
CommitLineData
ca92fb37
PP
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
12namespace 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 */
26class DataLen final
27{
28private:
29 constexpr explicit DataLen(const unsigned long long lenBits) noexcept : _mLenBits {lenBits}
30 {
31 }
32
33public:
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
149private:
150 unsigned long long _mLenBits = 0;
151};
152
153static inline DataLen operator+(const DataLen lenA, const DataLen lenB) noexcept
154{
155 return DataLen::fromBits(safeAdd(*lenA, *lenB));
156}
157
158static inline DataLen operator-(const DataLen lenA, const DataLen lenB) noexcept
159{
160 return DataLen::fromBits(safeSub(*lenA, *lenB));
161}
162
163static 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 */
176namespace literals {
177namespace datalen {
178
179static inline DataLen operator""_bits(const unsigned long long val) noexcept
180{
181 return DataLen::fromBits(val);
182}
183
184static inline DataLen operator""_KiBits(const unsigned long long val) noexcept
185{
186 return DataLen::fromBits(safeMul(val, 1024ULL));
187}
188
189static inline DataLen operator""_MiBits(const unsigned long long val) noexcept
190{
191 return DataLen::fromBits(safeMul(val, 1024ULL * 1024));
192}
193
194static inline DataLen operator""_GiBits(const unsigned long long val) noexcept
195{
196 return DataLen::fromBits(safeMul(val, 1024ULL * 1024 * 1024));
197}
198
199static inline DataLen operator""_bytes(const unsigned long long val) noexcept
200{
201 return DataLen::fromBytes(val);
202}
203
204static inline DataLen operator""_KiBytes(const unsigned long long val) noexcept
205{
206 return DataLen::fromBytes(safeMul(val, 1024ULL));
207}
208
209static inline DataLen operator""_MiBytes(const unsigned long long val) noexcept
210{
211 return DataLen::fromBytes(safeMul(val, 1024ULL * 1024));
212}
213
214static 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.029481 seconds and 4 git commands to generate.