Line data Source code
1 : /***************************************************************************\
2 : * Name : bitfields *
3 : * Description : bitfields checks *
4 : * Author : antonin.kriz@gmail.com *
5 : * ------------------------------------------------------------------------- *
6 : * This is free software; you can redistribute it and/or modify it under the *
7 : * terms of the MIT license. A copy of the license can be found in the file *
8 : * "LICENSE" at the root of this distribution. *
9 : \***************************************************************************/
10 : #pragma once
11 :
12 : #include <cassert>
13 : #include <climits>
14 : #include <cstdint>
15 : #include <stdexcept>
16 :
17 : namespace spb::detail
18 : {
19 : template <typename T>
20 : concept signed_int = std::is_signed_v<T> && std::is_integral_v<T>;
21 :
22 : template <typename T>
23 : concept unsigned_int = !std::is_signed_v<T> && std::is_integral_v<T>;
24 :
25 264 : static inline void check_if_value_fit_in_bits(signed_int auto value, uint32_t bits)
26 : {
27 264 : assert(sizeof(value) * CHAR_BIT >= bits);
28 264 : assert(bits > 0);
29 :
30 264 : decltype(value) max = (1LL << (bits - 1)) - 1;
31 264 : decltype(value) min = -(1LL << (bits - 1));
32 :
33 264 : if ((value < min) | (value > max)) [[unlikely]]
34 56 : throw std::runtime_error("bitfield overflow");
35 208 : }
36 :
37 203 : static inline void check_if_value_fit_in_bits(unsigned_int auto value, uint32_t bits)
38 : {
39 203 : assert(sizeof(value) * CHAR_BIT >= bits);
40 :
41 203 : decltype(value) max = (1LL << bits) - 1;
42 :
43 203 : if (value > max) [[unlikely]]
44 37 : throw std::runtime_error("bitfield overflow");
45 166 : }
46 :
47 : } // namespace spb::detail
|