21 inline void set_mask_u8(
volatile u8& val, u8 mask) {val |= mask;}
22 inline void clr_mask_u8(
volatile u8& val, u8 mask) {val &= ~mask;}
30 inline void clr_mask(T& val, T mask) {val &= ~mask;}
32 inline void set_mask(T& val, T mask) {val |= mask;}
38 if (b) set_mask<T>(val, mask);
39 else clr_mask<T>(val, mask);
43 template <
typename T>
inline constexpr T
mask_lower(
unsigned n) {
44 return ((n >= 8*
sizeof(T)) ? 0 : (T(1) << n)) - 1;
55 constexpr
optional() : val_(), has_val_(false) {}
57 constexpr
optional(
const T& t) : val_(t), has_val_(true) {}
59 inline void reset() { has_val_ =
false; }
62 { val_ = t; has_val_ =
true;
return *
this; }
64 inline T
value()
const {
return val_; }
66 inline T
value_or(
const T& t)
const {
return has_val_ ? val_ : t; }
70 inline explicit operator bool()
const {
return has_val_; }
72 T val_;
bool has_val_;
99 inline constexpr u8
min_u8(u8 a, u8 b)
100 {
return (a < b) ? a : b;}
102 {
return (a < b) ? a : b;}
104 {
return (a < b) ? a : b;}
106 {
return (a < b) ? a : b;}
108 {
return (a < b) ? a : b;}
110 {
return (a < b) ? a : b;}
112 {
return (a < b) ? a : b;}
115 {
return (a > b) ? a : b;}
117 {
return (a > b) ? a : b;}
119 {
return (a > b) ? a : b;}
121 {
return (a > b) ? a : b;}
123 {
return (a > b) ? a : b;}
125 {
return (a > b) ? a : b;}
127 {
return (a > b) ? a : b;}
131 u32 max_u32(u32 a, u32 b, u32 c);
136 template <
typename T>
inline constexpr T
clamp(T x, T y) {
137 return (x < -y) ? -y : (x > y ? y : x);
143 {
return (u8)((a < 0) ? -a : +a);}
145 {
return (u16)((a < 0) ? -a : +a);}
147 {
return (u32)((a < 0) ? -a : +a);}
149 {
return (u64)((a < 0) ? -a : +a);}
153 template <
typename T>
inline constexpr T
sign(T x) {
154 return T((x < 0) ? -1 : (x > 0 ? 1 : 0));
164 u32 xx = (x < 0) ? -x : +x;
174 return (sum >= m) ? (sum - m) : sum;
177 return (sum >= m) ? (sum - m) : sum;
180 return (sum >= m) ? (sum - m) : sum;
183 return (sum >= m) ? (sum - m) : sum;
200 template <
typename T>
inline constexpr T
divide(T a, T b) {
201 return (a % b < 0) ? (a / b - 1) : (a / b);
203 template <
typename T>
inline constexpr T
modulo(T a, T b) {
204 return (a % b < 0) ? (a % b + b) : (a % b);
211 while (x > 1) { ++count; x = (x+1)/2; }
218 while (x > 1) { ++count; x /= 2; }
226 template <
typename T>
inline constexpr s64
round_s64(T x) {
227 return static_cast<s64
>(x + (T)(x < 0 ? -0.5 : 0.5));
229 template <
typename T>
inline constexpr u64
round_u64(T x) {
230 return static_cast<u64
>(x + (T)0.5);
249 template <
typename T>
251 return (a + b < c && a + b >= a) ? (a + b) : (c);
255 constexpr
double pow2d(
unsigned n) {
256 return (n < 64) ? (double(1ull << n)) : (
double(1ull << 63) *
pow2d(n-63));
261 template <
typename T>
inline constexpr T
div_floor(T a, T b)
262 {
return divide<T>(a, b);}
263 template <
typename T>
inline constexpr T div_round(T a, T b)
264 {
return divide<T>(a + b/2, b);}
265 template <
typename T>
inline constexpr T
div_ceil(T a, T b)
266 {
return divide<T>(a + b-1, b);}
269 {
return div_floor<u32>(a, b);}
271 {
return div_floor<s32>(a, b);};
273 {
return div_round<u32>(a, b);};
275 {
return div_round<s32>(a, b);};
277 {
return div_ceil<u32>(a, b);};
279 {
return div_ceil<s32>(a, b);};
283 bool is_multiple_u32(u32 a, u32 b);
286 unsigned popcount(u32 x);
291 return ((num & 0xFF00000000000000ull) >> 56)
292 | ((num & 0x00FF000000000000ull) >> 40)
293 | ((num & 0x0000FF0000000000ull) >> 24)
294 | ((num & 0x000000FF00000000ull) >> 8)
295 | ((num & 0x00000000FF000000ull) << 8)
296 | ((num & 0x0000000000FF0000ull) << 24)
297 | ((num & 0x000000000000FF00ull) << 40)
298 | ((num & 0x00000000000000FFull) << 56);
302 return ((num & 0xFF000000u) >> 24)
303 | ((num & 0x00FF0000u) >> 8)
304 | ((num & 0x0000FF00u) << 8)
305 | ((num & 0x000000FFu) << 24);
309 return ((num & 0xFF00u) >> 8) | ((num & 0x00FFu) << 8);
315 bool xor_reduce_u8(u8 x);
316 bool xor_reduce_u16(u16 x);
317 bool xor_reduce_u32(u32 x);
318 bool xor_reduce_u64(u64 x);
322 unsigned min_2n(u32 x, u32 y);
333 u16 extract_be_u16(
const u8* src);
334 u32 extract_be_u32(
const u8* src);
335 u64 extract_be_u64(
const u8* src);
340 void write_be_u16(u8* dst, u16 val);
341 void write_be_u32(u8* dst, u32 val);
342 void write_be_u64(u8* dst, u64 val);
348 if (x != y) {T z = *x; *x = *y; *y = z;}
351 if (x != y) {T z = x; x = y; y = z;}
357 template <
typename T>
void sort(T* begin, T* end) {
359 for (T* a = begin ; a+1 != end ; ++a) {
361 for (T* b = a+1 ; b != end ; ++b) {
362 if (*b < *min_ptr) min_ptr = b;
376 u32
next(u32 mn, u32 mx);
397 void update(
const char* lbl, u32 value);
408 enum {SATCAT5_LITTLE_ENDIAN = 0x03020100ul, SATCAT5_BIG_ENDIAN = 0x00010203ul};
409 constexpr
union {u8 bytes[4]; u32 value;} HOST_ORDER_CANARY = {{0,1,2,3}};
415 static_assert(
sizeof(T1) ==
sizeof(T2),
"Type size mismatch");
421 std::memcpy(&y, &x,
sizeof(T1));
Simple cross-platform psuedorandom number generator (PRNG).
void seed(u64 seed)
Reset to the provided PRNG state.
constexpr Prng(u64 seed=123456789ull)
Constructor sets initial PRNG state.
u32 next()
Range [0..2^32)
Running maximum with label tracking.
void clear()
Reset recorded maximum to zero.
void update(const char *lbl, u32 value)
Update stats if new value exceeds previous record.
u32 m_maximum
Maximum observed value.
const char * m_label
Human-readable label.
An optional field that may be filled or empty.
void reset()
Reset to the empty state.
bool has_value() const
Is this optional field present?
constexpr optional(const T &t)
Create a filled value.
T value() const
Fetch the inner value.
optional & operator=(const T &t)
Assign a filled value.
constexpr optional()
Create an empty value.
T value_or(const T &t) const
Fetch the inner value if present, or the specified default.
Basic type aliases and prototypes used throughout SatCat5.
constexpr s32 div_ceil_s32(s32 a, s32 b)
Integer division functions with various rounding options:
constexpr unsigned min_unsigned(unsigned a, unsigned b)
Min and max functions.
constexpr s32 div_round_s32(s32 a, s32 b)
Integer division functions with various rounding options:
void set_mask_u32(u32 &val, u32 mask)
Set or clear bit masks.
u32 square_u16(u16 x)
Square an input (and double output width)
constexpr unsigned modulo_add_uns(unsigned sum, unsigned m)
Modulo addition function.
void clr_mask(T &val, T mask)
Set or clear bit masks.
constexpr T modulo(T a, T b)
Portability wrapper for platforms with signed division and modulo:
void clr_mask_u16(u16 &val, u16 mask)
Set or clear bit masks.
constexpr double pow2d(unsigned n)
Calculate 2^N for very large N, returning a double.
constexpr u32 max_s32(s32 a, s32 b)
Min and max functions.
void swap_ref(T &x, T &y)
Swap two values using a temporary variable.
constexpr u32 HOST_BYTE_ORDER()
Cross-platform determination of native byte-order.
constexpr u64 round_s64z(T x)
Variant of "round_u64" that returns zero if input is out of range.
constexpr u64 max_s64(s64 a, s64 b)
Min and max functions.
constexpr u8 min_u8(u8 a, u8 b)
Min and max functions.
constexpr u32 modulo_add_u64(u64 sum, u64 m)
Modulo addition function.
constexpr u8 max_u8(u8 a, u8 b)
Min and max functions.
T2 reinterpret(T1 x)
In-place byte-for-byte format conversion, aka "type-punning".
constexpr u64 round_u64z(T x)
Variant of "round_u64" that returns zero if input is out of range.
constexpr u32 div_round_u32(u32 a, u32 b)
Integer division functions with various rounding options:
constexpr u64 round_u64(T x)
Round a floating-point value to the nearest integer.
u32 square_s16(s16 x)
Square an input (and double output width)
constexpr u16 modulo_add_u16(u16 sum, u16 m)
Modulo addition function.
constexpr u16 reverse_bytes_u16(u16 num)
Reverse the order of bytes in an integer.
void clr_mask_u8(volatile u8 &val, u8 mask)
Set or clear bit masks.
constexpr s32 div_floor_s32(s32 a, s32 b)
Integer division functions with various rounding options:
void set_mask_if(T &val, T mask, bool b)
Call set_mask or clr_mask depending on the third argument.
constexpr u64 abs_s64(s64 a)
Absolute value.
void set_mask_u8(volatile u8 &val, u8 mask)
Set or clear bit masks.
void clr_mask_u32(u32 &val, u32 mask)
Set or clear bit masks.
constexpr T clamp(T x, T y)
Template "clamp" function.
constexpr u32 min_u32(u32 a, u32 b)
Min and max functions.
constexpr u32 reverse_bytes_u32(u32 num)
Reverse the order of bytes in an integer.
void swap_ptr(T *x, T *y)
Swap two values using a temporary variable.
constexpr T sign(T x)
Sign function (-x/0/+x -> -1/0/+1)
constexpr u32 abs_s32(s32 a)
Absolute value.
unsigned log2_ceil(T x)
Calculate log2(x), rounding up.
bool countdown(T &timer, const T &decr)
Decrement a countdown timer, returning true if it reaches zero.
constexpr u32 modulo_add_u32(u32 sum, u32 m)
Modulo addition function.
constexpr T saturate_add(T a, T b, T c=T(-1))
Unsigned add with saturation: min(A + B, C).
constexpr u32 max_u32(u32 a, u32 b)
Min and max functions.
void set_mask(T &val, T mask)
Set or clear bit masks.
constexpr u64 min_u64(u64 a, u64 b)
Min and max functions.
constexpr unsigned max_unsigned(unsigned a, unsigned b)
Min and max functions.
constexpr u16 min_u16(u16 a, u16 b)
Min and max functions.
constexpr T div_ceil(T a, T b)
Integer division functions with various rounding options:
constexpr u64 max_u64(u64 a, u64 b)
Min and max functions.
constexpr union satcat5::util::@1 HOST_ORDER_CANARY
Cross-platform determination of native byte-order.
constexpr T mask_lower(unsigned n)
Return a bit-mask where the N LSBs are set.
constexpr u64 reverse_bytes_u64(u64 num)
Reverse the order of bytes in an integer.
constexpr u8 abs_s8(s8 a)
Absolute value.
constexpr T divide(T a, T b)
Portability wrapper for platforms with signed division and modulo:
constexpr u32 div_floor_u32(u32 a, u32 b)
Integer division functions with various rounding options:
constexpr s64 round_s64(T x)
Round a floating-point value to the nearest integer.
void sort(T *begin, T *end)
Templated in-place stable sort for small arrays.
constexpr u64 min_s64(s64 a, s64 b)
Min and max functions.
constexpr u16 max_u16(u16 a, u16 b)
Min and max functions.
constexpr T div_floor(T a, T b)
Integer division functions with various rounding options:
T poll_counter(T &ct, bool reset=true)
Poll a cumulative counter, optionally resetting it to zero.
constexpr u32 div_ceil_u32(u32 a, u32 b)
Integer division functions with various rounding options:
void set_mask_u16(u16 &val, u16 mask)
Set or clear bit masks.
unsigned log2_floor(T x)
Calculate log2(x), rounding down.
constexpr u16 abs_s16(s16 a)
Absolute value.
constexpr u32 min_s32(s32 a, s32 b)
Min and max functions.