bit_manipulation.h
Go to the documentation of this file.
1 #ifndef cetlib_bit_manipulation_h
2 #define cetlib_bit_manipulation_h
3 
4 // ======================================================================
5 //
6 // bit_manipulation: Compile-time bit manipulations
7 //
8 // ======================================================================
9 
10 #include <cstddef>
11 #include <limits>
12 #include <type_traits>
13 
14 namespace cet {
15 
16  /// struct bit_size<U>.
17  template <class U, bool = std::is_unsigned_v<U>>
18  struct bit_size;
19 
20  template <class U>
21  struct bit_size<U, true> {
22  static constexpr std::size_t value = std::numeric_limits<U>::digits;
23  };
24 
25  template <class U>
26  constexpr std::size_t bit_size_v = bit_size<U>::value;
27 
28  /// struct bit_number<U, n>.
29  template <class U, std::size_t n, bool = n<bit_size_v<U>> struct bit_number;
30 
31  template <class U, std::size_t n>
32  struct bit_number<U, n, true> {
33  static constexpr std::size_t value = U(1u) << n;
34  };
35 
36  template <class U, std::size_t n>
37  struct bit_number<U, n, false> {
38  static constexpr std::size_t value = U(0u);
39  };
40 
41  template <class U, std::size_t n>
42  constexpr std::size_t bit_number_v = bit_number<U, n>::value;
43 
44  /// struct right_bits<U, n>.
45  template <class U,
46  std::size_t n,
47  bool = std::is_unsigned_v<U>,
48  bool = (n + 1) < bit_size_v<U>>
49  struct right_bits;
50 
51  template <class U, std::size_t n>
52  struct right_bits<U, n, true, true> {
53  static constexpr U value = bit_number_v<U, n + 1> - static_cast<U>(1u);
54  };
55 
56  template <class U, std::size_t n>
57  struct right_bits<U, n, true, false> {
58  static constexpr U value = ~0u;
59  };
60 
61  template <class U, std::size_t n>
62  constexpr U right_bits_v = right_bits<U, n>::value;
63 
64  // struct left_bits<U, n>.
65  template <class U,
66  std::size_t n,
67  bool = std::is_unsigned_v<U>,
68  bool = n <= bit_size_v<U>>
69  struct left_bits;
70 
71  template <class U, std::size_t n>
72  struct left_bits<U, n, true, true> {
73  private:
74  static constexpr U n_zeros = bit_size_v<U> - n;
75 
76  public:
77  static constexpr U value = ~right_bits_v<U, n_zeros>;
78  };
79 
80  template <class U, std::size_t n>
81  struct left_bits<U, n, true, false> {
82  static constexpr U value = U(-1);
83  };
84 
85  // U circ_lshift<U>().
86  template <class U>
87  inline constexpr std::enable_if_t<std::is_unsigned_v<U>, U>
88  circ_lshift(U X, U n)
89  {
90  constexpr std::size_t nbits = bit_size_v<U>;
91  constexpr std::size_t mask = nbits - 1ul;
92  n %= nbits;
93  return (X << n) | (X >> (nbits - n) & mask);
94  }
95 }
96 #endif /* cetlib_bit_manipulation_h */
97 
98 // Local Variables:
99 // mode: c++
100 // End:
std::void_t< T > n
constexpr std::size_t bit_size_v
struct bit_size<U>.